Cấu Trúc Dữ Liệu Và Giải Thuật Chapter 3.2 Singlelist Tài Liệu Bao Gồm 6 Chapter Mong các bạn theo dõi đầy đủ để đạt kết quả cao . Để Cập Nhật Thêm Tìm Hiểu Hơn Nữa Về Tài Liệu IT Thì Các Bạn Có Thể Truy Cập : https:123doc.orgtrangcanhan4336953tailieuit.htm CẢM ƠN CÁC BẠN ĐÃ THEO DÕI
Trang 1Phần 2: Danh sách liên kết
Trang 2Danh sách liên kết
DSLK là cấu trúc dữ liệu động
Các phần tử trong danh sách (node) nằm rải rác trong bộ nhớ
Cấu trúc mỗi node:
Vùng dữ liệu
Vùng liên kết (chứa địa chỉ node kế tiếp hoặc node liền trước)
Thao tác thêm/xóa nút chỉ cần điều chỉnh lại các liên kết
Trang 3Danh sách liên kết (List)
Danh sách liên kết đơn: mỗi phần tử liên kết với phần tử đứng sau nó trong danh sách:
Danh sách liên kết đôi: mỗi phần tử liên kết với các phần tử đứng trước và sau nó trong
danh sách:
Trang 4 Danh sách liên kết vòng : phần tử cuối danh sách liên kết với phần tử đầu danh sách:
Danh sách liên kết (List)
Trang 5Danh sách liên kết đơn
Trang 6 Khái niệm DSLK đơn
Biểu diễn, quản lý DSLK đơn
Các thao tác trên DSLK đơn
Sao chép DSLK đơn
Sắp xếp trên DSLK đơn
Mục tiêu
Trang 7 DSLK đơn là chuỗi các node (nút), được tổ chức theo thứ tự tuyến tính
Phần Data: Lưu trữ dữ liệu
Phần liên kết: Lưu trữ địa chỉ của phần tử kế tiếp trong danh sách, hoạc lưu trữ giá trị NULL nếu là phần tử cuối cùng trong danh sách
Data Next Node
1 Khái niệm
Trang 8struct Node {
DataType data;
struct node *Next;
};
struct Node {
Cấu trúc node
DataType ?
2 Biểu diễn nút trong DSLK đơn
Trang 9 Để quản lý một DSLK đơn chỉ cần biết địa chỉ phần tử đầu danh sách
Con trỏ pHead sẽ được dùng để lưu trữ địa chỉ phần tử đầu danh sách:
NODE * pHead;
Để tiện lợi, có thể sử dụng thêm một con trỏ
pTail lưu địa chỉ phần tử cuối danh sách:
Trang 10 Khởi tạo danh sách
4 Các thao tác trên DSLK đơn
Trang 114.1 Khởi tạo danh sách
void KhoiTao (List &l){
l pHead = NULL; l.pTail = NULL; }
B1 Gán con trỏ pHead = NULL
B2 Gán con trỏ pTail = NULL
Trang 124.2 Tạo mới 1 nút trong danh sách
Thuật toán
+ Đầu vào: Thành phần dữ liệu x
+ Đầu ra: Nút chứa dữ liệu x
B1: p = new node; //cấp phát bộ nhớ cho con trỏ p B2: if (p == NULL) // cấp phát không thành công
Thực hiện BKT;
B3: p->data=x;
B4: p->next=NULL;
BKT: Kết thúc;
Trang 144.3 Thêm 1 phần tử vào danh sách
Thêm vào đầu danh sách
Thêm vào cuối danh sách
Thêm vào sau một nút q bất kỳ
Trang 15Thêm vào đầu danh sách
4.3 Thêm 1 phần tử vào danh sách
Trang 16Thêm phần tử vào đầu danh sách
Thuật toán
Đầu vào: Danh sách l, Nút p cần thêm vào l
Đầu ra: Danh sách l sau khi đã thêm nút p
Kiểm tra nếu DS rỗng thì:
Trang 17Thêm phần tử vào đầu danh sách
4.3 Thêm 1 phần tử vào danh sách
Trang 18Bài tập 1: Viết chương trình tạo 1 danh sách liên kết để lưu các số nguyên được nhập từ bàn phím
Bài tập áp dụng
Trang 19Thuật toán tạo 1 danh sách liên kết đơn:
• Đầu vào: các phần tử dữ liệu X = {x1, x2, x3, …xn}
• Đầu ra: Danh sách liên kết l
B1 Khai báo danh sách: List l;
B2 Khởi tạo danh sách
B3 Bước lặp:
Xét từng phần tử xi trong X, thực hiện:
+ Tạo mới một nút chứa xi;
+ Chèn nút vừa tạo vào danh sách;
Bài tập áp dụng
Trang 20Thêm phần tử vào sau phần tử q
4.3 Thêm 1 phần tử vào danh sách
Trang 21Thêm vào sau phần tử q
Thuật toán
• Đầu vào: Danh sách l, nút q, nút p (nút cần thêm
• Đầu ra: Danh sách l sau khi đã thêm nút p
B1 Kiểm tra nếu q!=NULL;
1.1: p->next = q->next;
1.2: q->next = p
1.3: Kiểm tra nếu q = pTail thì
+ Điểu chỉnh lại Tail = p;
Ngược lại, thực hiện B2
B2 Thêm vào đầu DS
4.3 Thêm 1 phần tử vào danh sách
Trang 22void ChenSau (List &l, node *q, Node *p)
Thêm phần tử vào sau phần tử q
4.3 Thêm 1 phần tử vào danh sách
Trang 23Thêm vào cuối danh sách
4.3 Thêm 1 phần tử vào danh sách
Trang 24Thuật toán:
B1 Kiểm tra nếu DS rỗng thì:
1.1: Gán pHead = p;
1.2: Gán pTail = p;
Ngược lại, thực hiện B2
B2: Chèn p vào cuối danh sách:
2.1: pTail->next = p;
2.2: Gán pTail=p;
BKT: Kết thúc;
Thêm vào cuối danh sách
4.3 Thêm 1 phần tử vào danh sách
Trang 25Thêm phần tử vào cuối danh sách
4.3 Thêm 1 phần tử vào danh sách
Trang 26Bài tập 2: Viết chương trình tạo 1 danh sách liên kết để lưu các số nguyên được nhập từ bàn phím Nhập vào một giá trị x và chèn x vào sau nút chứa giá trị y bất kỳ (y nhập từ bàn phím)
Bài tập áp dụng
Trang 27Bài tập 3: Viết chương trình tạo 1 danh sách gồm
n Nhân viên (mã nhân viên, họ tên, hs lương, năm công tác)
- Nhập thêm thông tin của 1 nhân viên và chèn vào sau nhân viên có mã = x (với x nhập từ bàn phím)
- Yêu cầu người dùng nhập lại nếu không tìm thấy nhân viên nào có mã = x
Bài tập áp dụng
Trang 28 Là thao tác thường dùng trong các loại DSLK
Phục vụ cho:
Hiển thị giá trị của các nút trong sanh sách
Lấy giá trị các nút để tính toán
Sắp xếp danh sách
Tìm kiếm một phẩn tử trong danh sách
Thao tác xử lý tùy thuộc vào từng bài toán
4.4 Duyệt danh sách
Trang 29Thuật toán:
Đầu vào: Danh sách cần duyệt l
Đầu ra: Tùy thuộc vào yêu cầu của bài toán
B1 Cho con trỏ p trỏ đến phần tử đầu danh sách;
B2: Bước lặp (thực hiện cho đến khi danh sách rỗng);
2.1: Xử lý phần tử p;
2.2: Cho p trỏ đến phần tử kế tiếp;
BKT: Kết thúc;
4.4 Duyệt danh sách
Trang 314.5 Tìm kiếm phần tử
Thuật toán
• Đầu vào: Danh sách l, khóa tìm kiếm x
• Đầu ra: Con trỏ tới nút chứa khóa cần tìm
B1: p=pHead // p trỏ đến đầu danh sách
B2: Trong khi (p!= NULL) và (p->data != x)
Thực hiện p = p->next; // p trỏ tới phần tử kế
BKT:
Nếu p!=NULL thi p trỏ tới phần tử cần tìm;
Ngược lại: không có phần tử cần tìm;
Trang 334.6 Xóa phần tử
Xóa phần tử ở đầu danh sách
Xóa phần tử ngay sau phần tử q
Xóa phần tử có khóa k bất kỳ
Trang 34Xóa phần ở đầu danh sách
4.6 Xóa phần tử
Trang 35Thuật toán:
Đầu vào: Danh sách l
Đầu ra: Danh sách l sau khi đã xóa phần tử ở đầu
Nếu (pHead !=NULL) thì:
B1: p = pHead; //p là phần tử cần xóa
B2: pHead = pHead->next //Điều chỉnh lại liên kết
B3: p->Next = NULL;
B4: free(p); //giải phóng bộ nhớ
B5: Nếu pHead=NULL thì pTail= NULL // DS rỗng
Xóa phần ở đầu danh sách
4.6 Xóa phần tử
Trang 37Bài tập 2: Mở rộng chương trình đã viết
- Bổ sung thêm thao tác xóa phần tử ở đầu danh sách
- Chương trình chính:
- + Tạo một danh sách lưu n số nguyên
+ Xóa phần tử ở đầu danh sách
+ Hiển thị danh sách trước và sau khi xóa
Bài tập áp dụng
Trang 38Xoá phần tử ngay sau phần tử q
4.6 Xóa phần tử
Trang 39Thuật toán:
Kiểm tra nếu q!=NULL thì
B1: p = q->next; //p là phần tử cần xóa
B2: nếu (p!=NULL) thì //q không phải cuối DS
2.1: Kiểm tra nếu p==pTail thì + Điều chỉnh lại liên kết pTail = q;
Ngược lại, thực hiện bước 2.2
2.2: q->next=p->next;
B3: free(p); //giải phóng bộ nhớ
Xoá phần tử ngay sau phần tử q
4.6 Xóa phần tử
Trang 41Thuật toán:
Đầu vào: Danh sách l, giá trị khóa k
Đầu ra: Danh sách l sau khi đã xóa phần tử có khóa k
B1: Tìm phần tử p có khoá k và phần tử q đứng trước p; B2: Nếu tìm thấy thì:
2.1: Kiểm tra nếu p là đầu danh sách thì:
+ Xoá phần tử ở đầu danh sách;
2.2: Nếu p không phải đầu danh sách:
Kiểm tra nếu p là cuối danh sách thì: pTail = q;
Ngược lại, điều chỉnh liên kết q->next = p->next;
Xoá phần tử có khóa k bất kỳ
4.6 Xóa phần tử
Trang 42int XoaNut (List &l, int k) {
Trang 434.7 Hủy danh sách
Thực chất là hủy từng nút
Thao tác này được thực hiện khi không cần dùng
đến danh sách nữa
Thuật toán:
Đầu vào: Danh sách liên kết;
Đầu ra: Danh sách bị hủy
B1: Xuất phát từ đầu danh sách;
B2: Lặp trong khi DS chưa rỗng
p = pHead;
pHead = pHead->next;
Huỷ p
B3: pTail=NULL;
Trang 45Sắp xếp DSLK đơn
Trang 47Cài đặt lại trên danh sách liên kết một trong những thuật toán sắp xếp đã biết trên mảng
Điểm khác biệt duy nhất là cách thức truy xuất đến các phần tử trên danh sách liên kết thông qua liên kết thay vì chỉ số như trên mảng
Do thực hiện hoán vị nội dung của các phần tử nên đòi hỏi sử dụng thêm vùng nhớ trung gian chỉ thích hợp với các xâu có các phần tử có thành phần data kích thước nhỏ
Khi kích thước của trường data lớn, việc hoán vị giá trị của hai phân tử sẽ chiếm chi phí đáng kể
Sắp xếp danh sách
Hoán vị nội dung các phần tử:
Trang 53void InterChangeSort ( List &l )
{
Node *p, *q;
for (p = l.pHead ; p!=l.pTail ; p=p->Next )
for (q = p->Next; q!=NULL ; q=q->Next )
Trang 59void SelectionSort (LIST &l)
{
{
}
}
2 Phương pháp chọn
Trang 65void BubleSort (List l)
{
Node *p, *q, *t, *t1;
t = l.pTail ;
for (p = l.pHead ; p != NULL ; p = p->Next) {
for (q = l.pHead; q!=t ; q=q->Next){
if( q->data > q->Next->data )
Swap ( q->data , q->Next->data);