Tiểu luận Cấu trúc dữ liệu và giải thuật Đề tài: Nghiên cứu và cài đặt chương trình thực hiện các phép toán bổ sung và loại bỏ phần tử đối với danh sách móc nối đơn và danh sách móc nối kép

34 1.7K 5
Tiểu luận Cấu trúc dữ liệu và giải thuật Đề tài: Nghiên cứu và cài đặt chương trình thực hiện các phép toán bổ sung và loại bỏ phần tử đối với danh sách móc nối đơn và danh sách móc nối kép

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

Thông tin tài liệu

Lời nói đầu ****** Ngày nay, khoa học kĩ thuật ngày phát triển, đặc biệt ngành công nghệ thông tin Ứng dụng công nghệ tràn ngập mặt đời sống Từ vật chất điện thoại, tivi, tủ lạnh, điều hòa, điều khiển máy … tới mạng xã hội facebook, zalo, google ….tất ứng dụng công nghệ thông tin Thế giới ngày đại nghành cơng nghệ thơng tin ngày phát triển Chính tầm quan trọng đa dạng ngành công nghệ thơng tin mà địi hỏi sinh viên cơng nghệ thông tin cần phải nắm vững nguyên lý ứng dụng của môn học công nghệ thông tin nói chung mơn cấu trúc liệu giải thuật nói riêng Mơn học trang bị cho sinh viên kiến thức cấu trúc liệu thiết kế cài đặt phần mềm Trong phạm vi mơn học, nhằm tìm hiểu danh sách liên kết ,tác giả xin trình bày đề tài: Nghiên cứu cài đặt chương trình thực phép toán bổ sung loại bỏ phần tử danh sách móc nối đơn danh sách móc nối kép Giới thiệu đề tài I Phát biểu để tài: Nghiên cứu cài đặt chương trình thực phép toán bổ sung loại bỏ phần tử danh sách móc nối đơn danh sách móc nối kép Đối tượng: - Danh sách liên kết đơn - Danh sách liên kết kép Mục tiêu: - Tìm hiểu trỏ - tìm hiểu cấu trúc liệu danh sách liên kết đơn - Tìm hiểu cấu trúc danh sách liên kết kép - Tìm hiểu thuật tốn chương trình sử dụng cài đặt tốn loại bỏ, bổ sung phần tử danh sách liên kết đơn , danh sách liên kết kép , ghép danh sách liên kết đơn, ghép danh sách liên kết kép Phạm vi: - Nghiên cứu lý thuyết môn học “Cấu trúc liệu giải thuật” - Nghiên cứu trọng tâm lý thuyết lý thuyết liệu trỏ - Nghiên cứu trọng tâm lý thuyết danh sách liên kết đơn , danh sách liên kết kép - Cài đặt chương trình thực phép toán bổ sung loại bỏ phần tử danh sách móc nối đơn danh sách móc nối kép, ghép danh sách liên kết đơn, danh sách liên kết kép Phương pháp nghiên cứu : - Nghiên cứu lý thuyết từ giáo trình mơn học “Cấu trúc liệu giải thuật” “giáo trình lập trình C++” , tìm hiểu tài liệu từ nguồn thơng tin web , từ viết chương trình C++, chạy thử kiểm tra đọ xác chương trình II Lý thuyết Danh sách liên kết Danh sách liên kết danh sách mà phần tử liên kết với nhờ vào vùng liên kết chúng Mỗi phần tử danh sách lưu trữ phần tử nhớ gồm số đơn vị nhớ gọi nút Mỗi nút có thành phần : + Trường liệu : Lưu trữ thông liệu nút + Trường trỏ : chứa địa nút hay trước Danh sách liên kết đơn a Khái niệm -Danh sách liên kết đơn danh sách mà phần tử sử dụng trỏ để tổ chức lưu trữ b Khai báo Mỗi nút gồm trường: + Trường liệu: lưu thông tin liệu nút, trường có trường liệu nhỏ + Trường trỏ: chứa địa nút đứng sau (trỏ tới nút đứng sau) A B C D Các phần tử danh sách liên kết chứa vùng không gian nhớ không kề nhớ.chúng nối với nhờ vào vùng liên kết Vùng liên kết phần tử thứ chứa địa phần tử thứ hai, liên kết phần tử thứ hai chứa địa phần tử thứ ba , phần tử cuối Riêng nút cuối (do nút sau nó) nên trường trỏ phải địa đặc biệt mà ta phải gọi địa (con trỏ ) null ( địa rỗng ) Để truy cập vào danh sách nối đơn, ta sử dụng trỏ L (list) trỏ tới nút danh sách Khi danh sách rỗng (danh sách khơng có phần tử nào) L=null -Quy ước phép toán: + X AVAIL : Phép thu hồi nút X hay phép trả có địa X danh sách chỗ trống - Quy ước việc truy cập nút + Với nút trỏ trỏ P: dulieu (P) : trường liệu nút P contro (P): trường trỏ nút P Riêng nút cuối khơng có nút đứng sau nên ta quy ước trường trỏ null Ví dụ danh sách khách hàng có số điện thoại tăng dần chứa danh sách sau: Vị trí 0000 0022 0033 0044 0055 Họ tên khách hàng Nguyễn Thị Linh Kim Thị Hải Hà Nguyễn Thị Trang Nguyễn Thị Hằng Đinh Thị Oanh Điện thoại 8631517 8632875 8643296 8655782 8678431 Liên kết 0055 0033 Null 0000 0022 Với cách tổ chức loại bỏ phần tử ta cần thay đổi vùng liên kết phần tử đứng trước (theo liên kết) đến phần tử đứng sau c Các giải thuật đặc trưng danh sách liên kết đơn Cho L trỏ cực trái R trỏ cực phải danh sách liên kết kép M trỏ, tỏ vào mộ nút tron danh sách Lập giải thuật bổ sung nút vào trước nút M, liệu nút X Danh sách liên kết kép a Khái niệm - Danh sách liên kết kép danh sách mà phần tử danh sách có kết nối với phần tử đứng trước phần tử đứng sau Danh sách liên kết kép xác định hai trỏ: - left trỏ vào node - right trỏ vào node cuối b Khai báo Danh sách nối kép gồm nút nối với theo chiều Mỗi nút mọt ghi (record) gồm ba trường: - Trường thứ chứa giá trị lưu nút - Trường thứ hai (Next) chứa liên kết (con trỏ) tới nút kế tiếp, tức chứa thông tin đủ để biết nút nút nút nào, trường hợp nút cuối (khơng có nút kế tiếp), trường liên kết gán giá trị đặc biệt - Trường thứ ba (Prev) chứa liên kết (con trỏ) tới nút liền trước, tức chứa thơng tin đủ để biết nút đứng trước nút danh sách nút nào, trường hợp nút (khơng có nút liền trước) trường gán giá trị đặc biệt Liên kết sau Data Giá trị Liên kết trước Khác với danh sách nối đơn, danh sách nối kép có hai chốt: - Nút danh sách gọi First - Nút cuối danh sách gọi Last Để duyệt danh sách nối kép, ta có hai cách: - Hoặc First, dựa vào liên kết Next để sang nút kế tiếp, đến gặp giá trị đặc biệt (duyệt qua nút cuối) dừng lại - Hoặc Last, dựa vào liên kết Prev để sang nút liền trước Việc chèn / xóa vào danh sách nối kép đơn giản kỹ thuật chỉnh lại mối liên kết nút cho hợp lý Việc chèn / xóa vào danh sách nối kép đơn giản kỹ thuật chỉnh lại mối liên kết nút cho hợp lý Ví dụ cần in danh sách theo thứ tự số điện thoại ta duyệt theo liên kết thứ hai: Vị trí 0000 0022 0033 0044 0055 Họ tên khách hàng Kim Hải Hà Nguyễn Thu Hằng Nguyễn Thị Linh Đinh Thị Oanh Phạm Thị Trang Điện thoại 8632215 8633341 8674532 8681123 8694567 Liên kết 0110 Nil 0000 0022 0044 Liên kết 0055 0110 Nil 0000 0022 Tổ chức danh sách liên kết kép: Trong nút ngồi phần Data cịn có hai trỏ: trỏ đến nút đứng trước trỏ đến nút đứng sau Như cấu trúc nút đưuọc biểu diễn sau: Lptr Data Trong đó: Data chứa số liệu nút Lptr: trỏ trái, trỏ tới nút đứng trước Rptr: trỏ phải, trỏ tới nút đứng sau Lptr nút cực trái Rptr nút cực phải Nil c Các giải thuật dặc trưng Rptr Cho L trỏ cực trái R trỏ cực phải danh sách liên kết kép M trỏ, tỏ vào mộ nút tron danh sách Lập giải thuật bổ sung nút vào trước nút M, liệu nút X III Cơ sở CTDL GT a Danh sách móc nối đơn a Phép bổ sung thêm phần tử vào danh sách nối đơn BÀI TOÁN: Cho danh sách nối đơn L Viết giải thuật bổ sung thêm phần tử New có trường liệu lấy từ nhớ có địa X vào sau nút trỏ M danh sách nối đơn GIẢI THUẬT: Void LInset(L, M, X) { Xin cấp phát nút mới} New AVAIL; Dulieu(New)= X; { Bổ sung} If (L== null){ danh sách rỗng} { L= New; Contro(New):= null; } Else {trường hợp tổng quát} { Contro(New)= contro(M); Contro(M)= New; } Return; Phép loại bỏ phần tử khỏi danh sách nối đơn BÀI TOÁN: Cho danh sách nối đơn L, viết giải thuật loại bỏ nút trỏ M danh sách nối đơn GIẢI THUẬT: Void LDelete(L, M) {kiểm tra danh sách có rỗng khơng} If (L== null) { b a Printf(“ danh sách rỗng”); Return; } {loại bỏ} If M= L { L= contro(M); M AVAIL; } Else { P= L; While (contro(P) != M) P= contro(P); Contro(P)= Contro(M); } MAVAIL; Return; Phép ghép hai danh sách nối đơn thành danh sách BÀI TOÁN: Cho danh sách nối đơn P, Q Viết giải thuật ghép danh sách thành danh sách cho P trỏ tới nút danh sách kết GIẢI THUẬT: Procedure GHEP(P, Q) If (Q== null) Return; If (P== null) P= Q; If (P!= null) and (Q!=null) { P1= P; While (contro(P)!=null) P1:= contro(P1); Contro(P1):= Q; } Return; Danh sách móc nối kép Giải thuật bổ sung thêm nút vào danh sách nối kép b BÀI TOÁN: Cho danh sách nối kép L, R viết giải thuật bổ sung thêm phần tử New có trường liệu lấy từ ô nhớ có địa X tử danh sách vào trước nút trỏ M GIẢI THUẬT: Void DLInsert(L, R, M, X) { Xin cấp phát nút} New AVAIL; Dulieu(New)=X; {Bổ sung vào danh sách rỗng} If (L==null) { L=R= New; Trotruoc(New)=trosau(New)= null; } {Bổ sung thêm đầu dãy} If (M==L) { Trotruoc(New)= null; Trosau(New)=M; Trotruoc(M)= New; L=New; } {tổng quát} Else { Trotruoc(New)= trotruoc(M); Trosau(New)= M; Trotruoc(M)=New; Trosau(trotruoc(New))= New; } Return; Giải thuật loại bỏ phần tử khỏi DS nối kép BÀI TOÁN: Cho DS nối kép L, R Hãy viết giải thuật loại bỏ nút M khỏi DS GIẢI THUẬT: Void DLDetele(L,R,M) {Kiểm tra xem danh sách rỗng không} If (L==null) { c Printf(“Danh sách rỗng”); Return; } {loại bỏ} If (L==R){danh sách bị rỗng sau loại bỏ} L=R=null; If (M==L){ loại bỏ nút cực trái} { L= trosau(M); Trotruoc(L)= null; } If (M==R){ loại bỏ nút cực phải} { R= trotruoc(M); Trosau(R)= null; } Else { Trosau(trotruoc(M))= trosau(M); Trotruoc(trosau(M))= trotruoc(M); } MAVAIL; Return; Giải thuật ghép hai danh sách móc nối kép BÀI TOÁN: Cho danh sách nối kép P, Q Viết giải thuật ghép danh sách thành danh sách GIẢI THUẬT: Procedure GHEP(P1, Q1, P2,Q2) If (P1== null) and (Q1==null) { Printf(“Danh sách thứ rỗng”); P=P2; Q=Q2; } If (P2==null) and (Q2==null) { Printf(“Danh sách thứ rỗng”); P=P1; Q=Q1; } Node *Tail; //con tro cuoi }; void Init(DList &L); //Khoi tao DS rong int Isempty (DList L); //kiem tra DS co rong hay khong int Len (DList L); // Do dai danh sach Node *Make_Node (Node *P, item x); //tao Node P chua thong tin la x void Insert_first (DList &L, item x); //Chen x vao vi tri dau tien danh sach void Insert_last (DList &L, item x); //Chen x vao vi tri dau tien danh sach void Insert_k (DList &L, item x, int k); //chen x vao vi tri k danh sach void Del_first (DList &L, item &x); //Xoa phan tu dau tien void Del_k (DList &L, item &x, int k); //Xoa Node k danh sach int Search (DList L, item x); //tim x danh sach void Del_x (DList &L, item x); //xoa phan tu x danh sach void Input (DList &L); //nhap danh sach void Output (DList L); //xuat danh sach void Init(DList &L) { L.Head = NULL; // Con tro dau tro den NULL L.Tail = NULL; // Con tro cuoi tro den NULL } int Isempty (DList L) //kiem tra DS rong { return (L.Head == NULL); } int Len (DList L) // Do dai danh sach { Node *PH = L.Head, *PT = L.Tail; //tao Node PH (con tro duyet tu dau DS) và PT (con tro duyet tu cuoi DS) de duyet danh sach L int i = 0; //bien dem if (PH != NULL) i = 1; while (PH != NULL) //trong P chua tro den NULL (cuoi danh sach thi lam) { if (PH == PT) break; PH = PH->Right; //cho PH tro den Node tiep theo i++; if (PH == PT) break; PT = PT->Left; //cho PT tro den Node truoc i++; } return i; //tra lai so Node cua L } Node *Make_Node (item x) //tao Node P chua thong tin la x { Node *P = (Node *) malloc (sizeof (Node)); //Cap phat vung nho cho P P->Data = x; //Ghi du lieu vao Data P->Left = NULL; P->Right = NULL; return P; } void Insert_first (DList &L, item x) //Chen x vao vi tri dau tien danh sach { Node *P; P = Make_Node(x); //tao Node P if (Isempty(L)) //Neu danh sach rong { L.Head = P; L.Tail = P; } else { P->Right = L.Head; L.Head->Left = P; L.Head = P; } } //Chen vao cuoi danh sach cung tuong tu void Insert_last (DList &L, item x) //Chen x vao vi tri cuoi danh sach { Node *P; P = Make_Node(x); //tao Node P if (Isempty(L)) //Neu danh sach rong { L.Head = P; L.Tail = P; } else { L.Tail->Right = P; //ket noi voi danh sach P->Left = L.Tail; //P tro ve Node truoc L.Tail = P; //luu lai vi tri cuoi } } void Insert_k (DList &L, item x, int k) //chen x vao vi tri k danh sach { Node *PH = L.Head, *PT, *R; int i=1, l = Len(L); if (k l+1) printf("Vi tri chen khong hop le !"); //kiem tra dieu kien else { R = Make_Node(x); //tao Node P if (k == 1) Insert_first(L,x); //chen vao vi tri dau tien else if (k == l+1) Insert_last(L,x); //chen vao vi tri cuoi else //chen vao vi tri 1Right; //xac dinh vi tri k R->Right = PT; //(1) R->Left = PH; //(2) PH->Right = R; //(3) PT->Left = R; //(4) } } } void Del_first (DList &L, item &x) //Xoa phan tu dau tien { if (!Isempty(L)) { x = L.Head->Data; //lay gia tri neu can dung L.Head = L.Head->Right; //Cho L tro den Node thu danh sach } } void Del_last (DList &L, item &x) //Xoa phan tu dau tien { if (!Isempty(L)) { x = L.Tail->Data; L.Tail = L.Tail->Left; L.Tail->Right = NULL; } } void Del_k (DList &L, item &x, int k) //Xoa Node k danh sach { Node *PH = L.Head, *PT; int i=1, l = Len(L); if (k l) printf("Vi tri xoa khong hop le !"); //kiem tra dieu kien else { if (k == 1) Del_first(L,x); //xoa vi tri dau tien else if (k == l) Del_last(L,x); //xoa vi tri cuoi else //xoa vi tri 1Right->Data; PT = PH->Right->Right; //xac dinh vi tri k+1 PH->Right = PT; PT->Left = PH; } } } int Search (DList L, item x) //tim x danh sach { Node *P=L.Head; int i=1; while (P != NULL && P->Data != x) //duyet danh sach den tim thay hoac ket thuc danh sach { P = P->Right; i++; } if (P != NULL) return i; //tra ve vi tri tim thay else return 0; //khong tim thay } void Del_x (DList &L, item x) //xoa phan tu x danh sach { int l = Search(L,x); while (l) { Del_k (L,x,l); //trong van tim thay x thi van xoa l = Search(L,x); } } void Input (DList &L) //nhap danh sach { int i=0; item x; { i++; printf ("Nhap phan tu thu %d : ",i); scanf("%d",&x); if (x != 0) Insert_k(L,x,Len(L)+1); } while(x != 0); //nhap de ket thuc } void Output (DList L) //xuat danh sach { Node *P=L.Head; while (P != L.Tail->Right) { printf("%5d",P->Data); P = P->Right; } printf("\n"); } int main() { DList L; Init(L); Input(L); Output(L); int lua_chon; printf("Moi ban chon phep toan voi DS LKD:"); printf("\n1: Kiem tra DS rong"); printf("\n2: Do dai DS"); printf("\n3: Chen phan tu x vao vi tri k DS"); printf("\n4: Tim mot phan tu DS"); printf("\n5: Xoa phan tu tai vi tri k"); printf("\n6: XOa phan tu x DS"); printf("\n7: Thoat"); { printf("\nBan chon: "); scanf("%d",&lua_chon); switch (lua_chon) { case 1: { if (Isempty(L)) printf("DS rong !"); else printf ("DS khong rong !"); break; } case 2: printf ("Do dai DS la: %d.",Len(L));break; case 3: { item x; int k; printf ("Nhap phan tu can chen vao DS: "); scanf("%d",&x); printf ("Nhap vi tri can chen: "); scanf ("%d",&k); Insert_k (L,x,k); printf ("DS sau chen:\n"); Output(L); break; } case 4: { item x; printf ("Moi ban nhap vao phan tu can tim: "); scanf("%d",&x); int k=Search(L,x); if (k) printf ("Tim thay %d DS tai vi tri thu: %d",x,k); else printf ("Khong tim thay %d danh sach !",x); break; } case 5: { int k; item x; printf ("Nhap vi tri can xoa: "); scanf ("%d",&k); Del_k (L,x,k); printf ("DS sau xoa:\n"); Output(L); break; } case 6: { item x; printf ("Nhap phan tu can xoa: "); scanf ("%d",&x); Del_x (L,x); printf ("DS sau xoa:\n"); Output(L); break; } case 7: break; } }while (lua_chon !=7); return 0; } Ghép danh sách nối kép #include #include #include typedef int item; typedef struct Node { item Data; Node *Left; Node *Right; }; typedef struct DList { Node *Head; Node *Tail; }; Node *GetNode(int x) { Node *P; P=new(Node); if(P==NULL) { printf("\n Khong du bo nho"); return NULL; } P->Data=x; P->Left = P->Right =NULL; return P; } void Init(DList &L) { L.Head = NULL; L.Tail = NULL; } void Addtail(DList &L, Node *new_e) { if(L.Head==NULL) { L.Head=L.Tail=new_e; } else { L.Tail->Right=new_e; L.Tail=new_e; } } void nhap(DList &L) { int i,n,x; Node *P; printf("\n Nhap so luong phan tu danh sach 1: "); scanf("%d",&n); for(i=1;iRight; } } int main() { DList L; Node *P; Init(L); nhap(L); xuat(L); getch(); } V Đánh giá kết nghiên cứu kết luận Danh sách móc nối đơn -Ưu điểm: + tận dụng không gian nhớ nhỏ để lưu trữ nút +Việc thêm, xóa phần tử danh sách liên kết dễ dàng, cần thay đổi mối liên kết phần tử với =>Danh sách liên kết đơn kiểu cấu trúc liệu phù hợp cho danh sách có nhiều biến động -Nhược điểm: + Mật độ sử dụng nhớ danh sách liên kết không tối ưu tuyệt đối + Việc truy xuất tìm kiếm phần tử danh sách liên kết nhiều thời gian phải duyệt qua phần tử danh sách + Bộ nhớ cần nhiều phải lưu them phần tử liên kết, vùng liệu lớn tỷ lệ mức sử dụng nhớ cao + số lần so sánh trung bình n/2 danh sách đặc dùng phương pháp tìm kiếm nhị phân số lần so sánh log2(n) Danh sách móc nối kép -Xâu kép mặt có tính chất giống xâu đơn Tuy nhiên có số tính chất khác xâu đơn sau: -Xâu kép có mối liên kết hai chiều nên từ phần tử truy xuất phần tử khác Trong xâu đơn ta truy xuất đến phần tử đứng sau phần tử cho trước Ðiều dẫn đến việc ta dễ dàng hủy phần tử cuối xâu kép, xâu đơn thao tác tồn chi phí O(n) -Bù lại, xâu kép tốn chi phí gấp đơi so với xâu đơn cho việc lưu trữ mối liên kết Ðiều khiến việc cập nhật nặng nề số trường hợp Như ta cần cân nhắc lựa chọn CTDL hợp lý cài đặt cho ứng dụng cụ thể Các tài liệu tham khảo: - Giáo trình Cấu trúc liệu giải thuật- Nxb Thống kê- Đại học kinh tế quốc dân

Ngày đăng: 05/05/2016, 00:23

Từ khóa liên quan

Tài liệu cùng người dùng

Tài liệu liên quan