Trong phạm vi môn học, nhằm tìm hiểu về danh sách liên kết ,tác giả xin trình bày đề 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 da
Trang 1Lời nói đầu
******
Ngày nay, nền khoa học kĩ thuật ngày càng phát triển, đặc biệt là ngành công nghệ thông tin Ứng dụng của công nghệ đã tràn ngập mọi mặt trong đời sống Từ vật chất như điện thoại, tivi, tủ lạnh, điều hòa, điều khiển máy … tới các mạng xã hội như facebook, zalo, google ….tất cả đều là ứng dụng của công nghệ thông tin Thế giới ngày càng hiện đại là do nghành công nghệ thông tin ngày càng phát triển Chính vì tầm quan trọng và đa dạng của ngành công nghệ thông tin mà đòi hỏi các sinh viên công nghệ thông tin cần phải nắm vững các nguyên lý và ứng dụng của của các môn học công nghệ thông tin nói chung và môn cấu trúc dữ liệu và giải thuật nói riêng Môn học trang bị cho sinh viên những kiến thức cơ bản về cấu trúc
dữ liệu khi thiết kế và cài đặt các phần mềm Trong phạm vi môn học, nhằm tìm hiểu về danh sách liên kết ,tác giả xin trình bày đề 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
I Giới thiệu đề tài.
1 Phát biểu để 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
2 Đối tượng :
- Danh sách liên kết đơn
- Danh sách liên kết kép
3 Mục tiêu :
Trang 2- Tìm hiểu về con trỏ
- tìm hiểu về cấu trúc dữ liệu của danh sách liên kết đơn
- Tìm hiểu về cấu trúc của danh sách liên kết kép
- Tìm hiểu về thuật toán chương trình được sử dụng khi cài đặt bài toán loại bỏ, bổ sung phần tử trên danh sách liên kết đơn , danh sách liên kết kép , ghép danh sáchliên kết đơn, ghép danh sách liên kết kép
4 Phạm vi:
- Nghiên cứu lý thuyết môn học “Cấu trúc dữ liệu và giải thuật”
- Nghiên cứu trọng tâm lý thuyết lý thuyết về dữ liệu con trỏ
- Nghiên cứu trọng tâm lý thuyết về 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 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, ghép 2 danh sách liên kết đơn, danh sách liên kết kép
5 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 dữ liệu và giải thuật” và
“giáo trình lập trình C++” , tìm hiểu tài liệu từ các nguồn thông tin web , từ đó viếtcác chương trình trên C++, chạy thử và kiểm tra đọ chính xác của chương trình
II Lý thuyết.
1 Danh sách liên kết
Danh sách liên kết là danh sách mà các phần tử được liên kết với nhau nhờ vào vùng liên kết của chúng
Mỗi phần tử của danh sách được lưu trữ trong 1 phần tử nhớ gồm một số đơn vị
bộ nhớ kế tiếp nhau được gọi là nút
Mỗi nút có 2 thành phần :
+ Trường dữ liệu : Lưu trữ thông dữ liệu của nút
Trang 3+ Trường con trỏ : chứa địa chỉ của nút kế tiếp hay trước nó
2 Danh sách liên kết đơn.
+ Trường con trỏ: chứa địa chỉ của nút đứng sau (trỏ tới nút đứng sau)
Các phần tử của danh sách liên kết được chứa ở vùng không gian nhớ không kề nhau trong bộ nhớ.chúng được nối với nhau nhờ vào vùng liên kết Vùng liên kết của phần tử thứ nhất chứa địa chỉ của phần tử thứ hai, cùng liên kết của phần tử thứhai chứa địa chỉ của phần tử thứ ba , cứ như thế cho đến phần tử cuối cùng
Riêng nút cuối cùng (do không có nút sau nó) nên trường con trỏ của nó phải là một địa chỉ đặc biệt mà ta phải gọi là địa chỉ (con trỏ ) null ( địa chỉ rỗng )
Để truy cập vào danh sách nối đơn, ta sử dụng một con trỏ L (list) trỏ tới nút đầu tiên của danh sách
Khi danh sách rỗng (danh sách không có phần tử nào) thì L=null
-Quy ước các phép toán:
+ X<= AVAIL : phép xin cấp phát 1 nút X từ danh sách chỗ trống hay phép xin 1 nút từ danh sách chỗ trống có địa chỉ X
+ X=> AVAIL : Phép thu hồi một nút X hay phép trả 1 có địa chỉ X về danh sách chỗ trống
Trang 4- Quy ước về việc truy cập một nút
+ Với 1 nút được trỏ bởi con trỏ P:
dulieu (P) : chỉ trường dữ liệu của nút P
.contro (P): chỉ trường con trỏ của nút P
Riêng nút cuối cùng thì không có nút đứng sau nên ta quy ước trường con trỏ của
c Các giải thuật đặc trưng của danh sách liên kết đơn.
Cho L là con trỏ cực trái và R là con trỏ cực phải của một danh sách
liên kết kép
M là con trỏ, tỏ vào mộ nút tron danh sách này
Lập giải thuật bổ sung một nút mới vào trước nút M, dữ liệu của nút mới là X
3 Danh sách liên kết kép
a Khái niệm
Trang 5- Danh sách liên kết kép là danh sách mà mỗi phần tử trong danh sách có kết nối với một phần tử đứng trước và một phần tử đứng sau nó.
Danh sách liên kết kép được xác định bởi hai con trỏ:
- left trỏ vào node đầu tiên
- right trỏ vào node cuối cùng
b Khai báo
Danh sách nối kép gồm các nút được nối với nhau theo 2 chiều Mỗi nút là mọt bảnghi (record) gồm ba trường:
- Trường thứ nhất chứa giá trị lưu trong nút đó
- Trường thứ hai (Next) chứa liên kết (con trỏ) tới nút kế tiếp, tức là chứa một thông tin đủ để biết nút kế tiếp nút đó là nút nào, trong trường hợp là nút cuối cùng(không có nút kế tiếp), trường liên kết này được gán một 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 là chứa một thông tin đủ để biết nút đứng trước nút đó trong danh sách là nút nào, trong trường hợp là nút đầu tiên (không có nút liền trước) trường này được gán một giá trị đặc biệt
Liên kết sau Data Giá trị
Khác với danh sách nối đơn, danh sách nối kép có hai chốt:
- Nút đầu tiên trong danh sách được gọi là First
- Nút cuối cùng trong danh sách được gọi là Last
Để duyệt danh sách nối kép, ta có hai cách:
Trang 6- Hoặc bắt đầu từ First, dựa vào liên kết Next để sang nút kế tiếp, đến khi gặp giá trị đặc biệt (duyệt qua nút cuối) thì dừng lại.
- Hoặc bắt đầu từ Last, dựa vào liên kết Prev để đi sang nút liền trước Việc chèn / xóa vào danh sách nối kép cũng đơn giản chỉ là kỹ thuật chỉnh lại các mối liên kết giữa các nút cho hợp lý
Việc chèn / xóa vào danh sách nối kép cũng đơn giản chỉ là kỹ thuật chỉnh lại
các mối liên kết giữa các nút cho hợp lý
Ví dụ cần in danh sách theo thứ tự số điện thoại thì ta duyệt theo liên kết thứ
hai:
Vị trí Họ tên khách hàng Điện thoại Liên kết 1 Liên kết 2
Data chứa số dữ liệu của nút
Lptr: con trỏ trái, trỏ tới nút đứng trước
Rptr: con trỏ phải, trỏ tới nút đứng sau
Lptr của nút cực trái và Rptr của nút cực phải là Nil
c Các giải thuật dặc trưng cơ bản
Trang 7Cho L là con trỏ cực trái và R là con trỏ cực phải của một danh sách liên kết
kép
M là con trỏ, tỏ vào mộ nút tron danh sách này
Lập giải thuật bổ sung một nút mới vào trước nút M, dữ liệu của nút mới là
X
III Cơ sở CTDL và GT
1 Danh sách móc nối đơn.
a Phép bổ sung thêm một phần tử vào danh sách nối đơnBÀI TOÁN: Cho một danh sách nối đơn L Viết giải thuật bổ sung thêm 1 phần tử New có trường dữ liệu lấy từ ô nhớ có địa chỉ X vào sau nút trỏ bởi M trong danh sách nối đơn
Contro(New):= null;
}
Else {trường hợp tổng quát}
{Contro(New)= contro(M);
Contro(M)= New;
}
3 Return;
a Phép loại bỏ 1 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ỏ 1 nút trỏ bởi M trong danh sách nối đơn trên
GIẢI THUẬT:
Void LDelete(L, M)
Trang 81 {kiểm tra danh sách có rỗng không}
b Phép ghép hai danh sách nối đơn thành một danh sách mới
BÀI TOÁN: Cho 2 danh sách nối đơn P, Q Viết giải thuật ghép 2 danh sách trên thành một danh sách và cho P trỏ tới nút đầu tiên của danh sách kết quả
Trang 9a Giải thuật bổ sung thêm một nút vào danh sách nối kép
BÀI TOÁN: Cho danh sách nối kép L, R hãy viết giải thuật bổ sung thêm một phần tử New có trường dữ liệu lấy từ ô nhớ có địa chỉ X tử danh sách vào trước nút trỏ bởi M
Trang 105 Return;
b Giải thuật loại bỏ một phần tử ra 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ỏ 1 nút Mkhỏi DS trên
Trang 11BÀI TOÁN: Cho 2 danh sách nối kép P, Q Viết giải thuật ghép 2 danh sách trên thành một danh sách.
GIẢI THUẬT:
Procedure GHEP(P1, Q1, P2,Q2)
1 If (P1== null) and (Q1==null)
{Printf(“Danh sách thứ nhất rỗng”);
typedef int item;
typedef struct Node //Cau truc cua 1 Node
{
item Data; //Du lieu cua Node
Node *next; //Con tro cua Node
Trang 12typedef Node *List; //List la mot danh sach cac Node
void Init (List &L); //khoi tao danh sach rong
int len (List L); // Do dai danh sach
Node *Make_Node (Node *P, item x); //Tao 1 Node P voi thong tin chu trong no
void Insert_first (List &L, item x); //Chen phan tu vao dau danh sachvoid Insert_k (List &L, item x, int k); //Chen phan tu vao vi tri k trongdanh sach
void Input (List &L); //Nhap danh sach
void Output (List L); //Xuat danh sach
int Search (List L, item x); //Tim phan tu x trong danh sach, ham tra
ve vi tri cua phan tu tim duoc
void Del_frist (List &L, item &x); //Xoa phan tu dau danh sach void Del_k (List &L, item &x, int k); //Xoa phan tu vi tri k trong danh sach
void Del_x (List &L, item x); //Xoa phan tu co gia tri x trong danh sach
void Init (List &L) // &L lay dia chi cua danh sach ngay khi truyen vao ham
Node *P=L; //tao 1 Node P de duyet danh sach L
int i=0; //bien dem
Trang 13while (P!=NULL) //trong khi P chua tro den NULL (cuoi danh sachthi lam)
{
i++; //tang bien dem
P=P->next; //cho P tro den Node tiep theo
P = Make_Node(P,x); //tao 1 Node P
P->next = L; //Cho P tro den L
Trang 14{
P = Make_Node(P,x); //tao 1 Node P
if (k == 1) Insert_first(L,x); //chen vao vi tri dau tien
else //chen vao k != 1
if (P != NULL) return i; //tra ve vi tri tim thay
else return 0; //khong tim thay
}
void Del_frist (List &L, item &x) //Xoa phan tu dau tien
{
x = L->Data; //lay gia tri ra neu can dung
L = L->next; //Cho L tro den Node thu 2 trong danh sach
Trang 15if (k==1) Del_frist(L,x); //xoa vi tri dau tien
else //xoa vi tri k != 1
Trang 16printf("\n5: Xoa phan tu tai vi tri k");
printf("\n6: Xoa phan tu x trong DS");
printf("\n7: Thoat");
do
Trang 17if (Isempty(L)) printf("DS rong !");
else printf ("DS khong rong !");
}
Trang 21typedef int item;
typedef struct Node //cau truc 1 Node
{
item Data; //du lieu cua Node
Node *Left; //Con tro trai
Node *Right; //con tro phai
};
typedef struct DList //cau truc Cua List
{
Node *Head; //con tro dau
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 1 Node P chua thong tin
la x
Trang 22void Insert_first (DList &L, item x); //Chen x vao vi tri dau tien trongdanh sach
void Insert_last (DList &L, item x); //Chen x vao vi tri dau tien trong danh sach
void Insert_k (DList &L, item x, int k); //chen x vao vi tri k trong 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 trong danh sachint Search (DList L, item x); //tim x trong danh sach
void Del_x (DList &L, item x); //xoa phan tu x trong 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
Trang 23PH = PH->Right; //cho PH tro den Node tiep theo
P = Make_Node(x); //tao 1 Node P
if (Isempty(L)) //Neu danh sach rong
Trang 24//Chen vao cuoi danh sach cung tuong tu
void Insert_last (DList &L, item x) //Chen x vao vi tri cuoi trong danh sach
{
Node *P;
P = Make_Node(x); //tao 1 Node P
if (Isempty(L)) //Neu danh sach rong
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
int i=1, l = Len(L);
if (k<1 || k> l+1) printf("Vi tri chen khong hop le !"); //kiem tra dieu kien
else
{
R = Make_Node(x); //tao 1 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 1<k<l+1
Trang 25x = L.Head->Data; //lay gia tri ra neu can dung
L.Head = L.Head->Right; //Cho L tro den Node thu 2 trong danhsach
Trang 26void Del_k (DList &L, item &x, int k) //Xoa Node k trong danh sach{
Node *PH = L.Head, *PT;
int i=1, l = Len(L);
if (k<1 || 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 1<k<l+1
Trang 27}
if (P != NULL) return i; //tra ve vi tri tim thay
else return 0; //khong tim thay
Trang 28printf("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 trong DS"); printf("\n4: Tim mot phan tu trong DS");
printf("\n5: Xoa phan tu tai vi tri k");
printf("\n6: XOa phan tu x trong DS");
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:
Trang 30typedef int item;
typedef struct Node
Trang 32printf("\n Nhap so luong phan tu danh sach 1: "); scanf("%d",&n);
Trang 33V. Đánh giá kết quả nghiên cứu và kết luận.
1 Danh sách móc nối đơn.
-Ưu điểm:
+ tận dụng được không gian bộ nhớ nhỏ để lưu trữ từng nút
+Việc thêm, xóa phần tử trong danh sách liên kết là dễ dàng, chỉ cần thay đổi mối liên kết của các phần tử với nhau
=>Danh sách liên kết đơn là kiểu cấu trúc dữ liệu phù hợp nhất cho các danh sách
có nhiều biến động
-Nhược điểm:
+ Mật độ sử dụng bộ nhớ của danh sách liên kết không tối ưu tuyệt đối
+ Việc truy xuất và tìm kiếm các phần tử trong danh sách liên kết mất nhiều thời gian vì phải duyệt tuần tự qua các phần tử trong danh sách
+ Bộ nhớ cần nhiều vì phải lưu them phần tử liên kết, nếu vùng dữ liệu là lớn thì tỷ
Trang 34đứng sau một phần tử cho trước Ðiều này dẫn đến việc ta có thể dễ dàng hủyphần tử cuối xâu kép, còn trên xâu đơn thao tác này 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ữ các mối liênkết Ðiều này khiến việc cập nhật cũng nặng nề hơn trong một số trường hợp Nhưvậy ta cần cân nhắc lựa chọn CTDL hợp lý khi cài đặt cho một ứng dụng cụ thể
3 Các tài liệu tham khảo:
- Giáo trình Cấu trúc dữ liệu và giải thuật- Nxb Thống kê- Đại học kinh tế quốcdân