Danh sách list trong cấu trúc dữ liệu
Trang 1Môn: CẤU TRÚC DỮ LIỆU
Chương 4: DANH SÁCH (LIST)
Trang 2NỘI DUNG CHƯƠNG 4
1. Khái niệm danh sách
2. Các phép toán trên danh sách
3. Danh sách đặc
Định nghĩa
Biểu diễn danh sách đặc
Các thao tác trên danh sách đặc
Ưu nhược điểm và ứng dụng
Trang 3xác định và giữa chúng có 1 mối quan hệ nào đó Nếu biết
phần tử ai vị trí của phần tử ai+1
Danh sách rỗng là danh sách có chiều dài = 0
gồm các phần tử thuộc kiểu T được định nghĩa là:
TX = < VX , OX >
Trong đó :
tử kiểu T }
1 phần tử vào danh sách; huỷ 1 phần tử khỏi danh sách; liệt kê danh sách, sắp xếp danh sách.}
Trang 42 Các phép toán trên danh sách
Tùy theo loại của từng danh sách sẽ có các phép toán khác nhau,
các phép toán thông thường như sau:
2.1 Tạo mới 1 danh sách
Đưa vào danh sách nội dung các phần tử
Chiều dài của danh sách là xác định
2.2 Thêm 1 phần tử vào danh sách
Khi thêm 1 phần tử chiều dài danh sách tăng lên
Có thao tác thêm vào đầu, cuối hay tại 1 vị trí xác định của
danh sách
2.3 Tìm kiếm 1 phần tử trong danh sách
Tìm 1 phần tử trong danh sách thỏa mãn điều kiện nào đó
Dùng các thuật toán tìm kiếm trong chương “Tìm kiếm”
2.4 Loại bớt 1 phần tử trong danh sách
Chiều dài danh sách giảm xuống 1 phần tử
Công việc loại bớt cũng bao gồm thao tác tìm kiếm ra phần tử
cần hủy trong danh sách
Trang 52 Các phép toán trên danh sách (tt)
2.5 Sửa đổi giá trị 1 phần tử trong danh sách
ra phần tử cần hủy trong danh sách
2.6 Sắp xếp danh sách
2.7 Tách danh sách thành nhiều danh sách con
Trang 63 Danh sách đặc (Condensed List)
3.1 Định nghĩa
các phần tử nằm kề cận nhau trong bộ nhớ
3.2 Biểu diễn danh sách đặc
liệu là kiểu dữ liệu của các phần tử trong danh sách
Trang 73 Danh sách đặc (tt)
3.3 Các thao tác trên danh sách đặc
Một số thao tác trên danh sách đặc được thống kê tóm tắt:
3.3.1 Khởi tạo danh sách
Khởi tạo danh sách cho chiều dài danh sách trở về 0
void CD_Initialize(int &Len)
{
Len = 0;
return;
}
Trang 83 Danh sách đặc (tt)
3.3 Các thao tác trên danh sách đặc (tt)
3.3.2 Tạo danh sách mới & nhập danh sách
Tạo danh sách mới có chiều dài tối đa MaxLen, hàm trả về giá trị thực
của danh sách mới được tạo.
int CD_Create_List(T M[], int &Len)
Trang 93 Danh sách đặc (tt)
3.3 Các thao tác trên danh sách đặc (tt)
3.3.3 Thêm 1 phần tử vào danh sách
Thêm 1 phần tử có giá trị NewValue vào trong danh sách có chiều dài
Length tại vị trí InsPos
Trang 103 Danh sách đặc (tt)
3.3 Các thao tác trên danh sách đặc (tt)
3.3.3 Thêm 1 phần tử vào danh sách (tt)
int CD_InsertElement(T M[], int &Len, T NewValue, int InsPos)
Trang 113 Danh sách đặc (tt)
3.3 Các thao tác trên danh sách đặc (tt)
3.3.4 Tìm kiếm 1 phần tử trong danh sách
Dùng các thuật toán tìm kiếm tìm phần tử thỏa mãn điều kiện
trong danh sách
Trang 123 Danh sách đặc (tt)
3.3 Các thao tác trên danh sách đặc (tt)
3.3.5 Hủy 1 phần tử trong danh sách
Loại bỏ phần tử có vị trí DelPosition trong danh sách M có chiều
dài Length (có thể có thao tác tìm kiếm xác định vị trí xóa phần tử) Thuật toán:
B1: IF(Length =0 OR DelPos > Len) Thực hiện BKT
Trang 133 Danh sách đặc (tt)
3.3 Các thao tác trên danh sách đặc (tt)
3.3.5 Hủy 1 phần tử trong danh sách (tt)
int CD_Delete_Element(T M[], int &Len, int DelPos)
Trang 143 Danh sách đặc (tt)
3.3 Các thao tác trên danh sách đặc (tt)
3.3.6 Sửa đổi giá trị cho 1 phần tử trong danh sách
Position trong danh sách M có chiều dài Length
(hay giá trị) và gán giá trị mới
Trang 153 Danh sách đặc (tt)
3.3 Các thao tác trên danh sách đặc (tt)
3.3.7 Sắp xếp thứ tự phần tử trong danh sách
Dùng các thuật toán sắp xếp nội
Trang 163 Danh sách đặc (tt)
3.3 Các thao tác trên danh sách đặc (tt)
3.3.8 Tách 1 danh sách thành nhiều danh sách
Có nhiều thao tác tách 1 danh sách thành nhiều danh sách:
danh sách con
Giả sử cần tách danh sách M có chiều dài Length thành các danh
sách con SM1, SM2 có chiều dài tương ứng là Slen1 và
SLen2
Trang 173 Danh sách đặc (tt)
3.3 Các thao tác trên danh sách đặc (tt)
3.3.8 Tách 1 danh sách thành nhiều danh sách (tt)
Trang 183 Danh sách đặc (tt)
3.3 Các thao tác trên danh sách đặc (tt)
3.3.8 Tách 1 danh sách thành nhiều danh sách (tt)
void CS_Split(T M[], int Len, T SM1[], int &SLen1, T SM2[], int &SLen2) { int (Slen1 >=Len)
if (SLen1 + SLen2 != Len) SLen2 = Len - SLen1;
for (int i=0; i<SLen1; i++) SM1[i] = M[i];
for (int j=0; j<SLen1; i++, j++) SM1[j] = M[i];
return;
}
Trang 193 Danh sách đặc (tt)
3.3 Các thao tác trên danh sách đặc (tt)
3.3.9 Nhập nhiều danh sách thành 1 danh sách
Các cách nhập danh sách:
dài là tổng chiều dài các danh sách
nào đó thành 1 danh sách mới (dùng thuật toán merge trong merge sort)
Giả sử cần ghép danh sách SM1, SM2 có chiều dài SLen1,
SLen2 thành danh sách M có chiều dài Len = SLen1+SLen2 theo thứ tự từ SM1 đến hết SM2
Trang 203 Danh sách đặc (tt)
3.3 Các thao tác trên danh sách đặc (tt)
3.3.9 Nhập nhiều danh sách thành 1 danh sách(tt)
Trang 213 Danh sách đặc (tt)
3.3 Các thao tác trên danh sách đặc (tt)
3.3.9 Nhập nhiều danh sách thành 1 danh sách(tt)
int CD_Concat(T SM1[], int SLen1, T SM2[], int SLen2, T M [], int
Trang 223 Danh sách đặc (tt)
3.3 Các thao tác trên danh sách đặc (tt)
3.3.10 Sao chép 1 danh sách: Sao chép nội dung danh sách thành 1
danh sách khác có cùng chiều dài
int CD_Copy(T M[], int Len, T CM[]) // Hàm trả về chiều dài của DS
{ for (int i=0; i< Len; i++)
CM[i] = M[i];
return (Len)
}
Trang 23dụng đưa chiều dài danh sách về 0, việc thu hồi bộ nhớ sẽ do ngôn ngữ lập trình thực hiện
Trang 243 Danh sách đặc (tt)
3.4 Ưu nhược điểm và ứng dụng
sách đặc có các ưu điểm:
tử liền kề với nhau trong bộ nhớ
trong danh sách cần dịch chuyển các phần tử còn lại qua vị trí khác
chiều, mảng nhiều chiều, mảng cấp phát tĩnh, mảng cấp phát động)
Trang 254.1 Định nghĩa
4.2 Danh sách liên kết đơn (Simply Linked List)
4.3 Danh sách liên kết kép (Doubly Linked List)
4.4 Ưu nhược điểm của danh sách liên kết
Trang 264 Danh sách liên kết (tt)
4.1 Định nghĩa
một sự nối kết với nhau thông qua vùng liên kết của chúng
tử khác, danh sách liên kết chia thành các loại khác nhau:
và thao tác trên dữ liệu khác nhau
Trang 284.2 Danh sách liên kết đơn (tt)
4.2.1 Cấu trúc dữ liệu (tt)
khác nhau, mỗi phương pháp sẽ có cấu trúc dữ liệu cụ thể
Quản lý địa chỉ phần đầu danh sách
SLLType SLList1;
Quản lý địa chỉ phần đầu và cuối danh sách
typedef struct SLL_PairNode
SLLType SLLLase;
} SLLPType;
SLLPType SLLList2;
Trang 304.2 Danh sách liên kết đơn (tt)
4.2.2 Các thao tác trên danh sách liên kết đơn
a Khởi tạo danh sách SLL
b Tạo mới 1 phần tử (nút) trong danh sách SLL
c Thêm 1 phần tử vào danh sách SLL
d Duyệt qua các nút trong danh sách
e Tìm kiếm phần tử trong danh sách
f Hủy bỏ 1 phần tử trong danh sách
g Hủy danh sách
h Tạo mới danh sách/Nhập danh sách
i Tách 1 danh sách thành nhiều danh sách
j Nhập nhiều danh sách thành 1 danh sách
k Sắp xếp thứ tự các phần tử trong danh sách
h Sao chép 1 danh sách
Trang 314.2 Danh sách liên kết đơn (tt)
4.2.2.a Khởi tạo danh sách SLL
quản lý địa chỉ đầu của danh sách về con trỏ NULL
void SLLInitialize(SLLType &First)
{
First = NULL;
return;
}
Trang 324.2 Danh sách liên kết đơn (tt)
4.2.2 b Tạo mới 1 phần tử (nút) trong danh sách SLL
Giả sử tạo mới 1 phần tử có thành phần dữ liệu = NewData
Trang 334.2 Danh sách liên kết đơn (tt)
4.2.2 b Tạo mới 1 phần tử (nút) trong danh sách SLL (tt)
Cài đặt
Prototype: SLLType SLLCreateNode(T NewData)
{
SLLType Pnode = New SLLOneNode;
if (Pnode != NULL)
{
Pnode ->NextNode = NULL;
Pnode ->Key = NewData;
}
return Pnode;
}
Trang 344.2 Danh sách liên kết đơn (tt)
4.2.2.c Thêm 1 phần tử vào danh sách SLL (Thêm đầu DS)
Trang 354.2 Danh sách liên kết đơn (tt)
4.2.2.c Thêm 1 phần tử vào danh sách SLL (Thêm đầu DS) (tt)
Trang 364.2 Danh sách liên kết đơn (tt)
4.2.2.c Thêm 1 phần tử vào danh sách SLL (tt) (Thêm giữa DS)
Trang 374.2 Danh sách liên kết đơn (tt)
4.2.2.c Thêm 1 phần tử vào danh sách SLL (Thêm giữa DS) (tt)
SLLType CurrNode = SList;
while (CurrNode->NextNode != NULL)
CurrNode = CurrNode-> NextNode;
CurrNode-> NextNode = NewNode;
return (SList);
}
Trang 384.2 Danh sách liên kết đơn (tt)
4.2.2.c Thêm 1 phần tử vào danh sách SLL (Thêm cuối DS)
Trang 394.2 Danh sách liên kết đơn (tt)
4.2.2.c Thêm 1 phần tử vào danh sách SLL (Thêm cuối DS) (tt)
Cài đặt
&InsNode)
if (InsNode->NextNode == NULL)
{ InsNode->NextNode = NewNode;
return (SList);
}
NewNode-> NextNode = InsNode->NextNode;
InsNode-> NextNode = NewNode;
return (SList);
}
Trang 404.2 Danh sách liên kết đơn (tt)
4.2.2.d Duyệt qua các nút trong danh sách liên kết đơn
Trang 414.2 Danh sách liên kết đơn (tt)
4.2.2.d Duyệt qua các nút trong danh sách liên kết đơn (tt)
Cài đặt:
{
SLLType CurrNode = SList;
while (CurrNode != NULL)
Trang 424.2 Danh sách liên kết đơn (tt)
4.2.2.e Tìm kiếm phần tử trong danh sách
Trang 434.2 Danh sách liên kết đơn (tt)
4.2.2.e Tìm kiếm phần tử trong danh sách (tt)
Cài đặt
{
SLLType CurrNode = SList;
while (CurrNode != NULL)
Trang 444.2 Danh sách liên kết đơn (tt)
4.2.2.f Hủy bỏ 1 phần tử trong danh sách
Loại bỏ phần tử (nút) có thành phần dữ liệu là DelData trong danh sách liên kết
đơn Gồm 2 thao tác: tìm phần tử có thành phần dữ liệu là DelData và loại bỏ phần
tử này (Trong quá trình tìm kiếm cần lưu trữ thành phần trước đó PreDelData)
B1: DelNode = SLList // Tìm kiếm phần tử có Key = DelData
B2: PreDelNode = NULL
B3: IF (DelNode == NULL) Thực hiện BKT
B4: IF (DelNode->Key == DelData) Thực hiện B8
Trang 454.2 Danh sách liên kết đơn (tt)
4.2.2.f Hủy bỏ 1 phần tử trong danh sách (tt)
Cài đặt thuật toán trong C++ (Hàm trả về giá trị 1 nếu hủy thành công)
int SLLDeleteNod e(SLLType &SList, T DelData)
{ SLLType DelNode = SList;
SLLType PreDelNode = NULL;
while (DelNode != NULL)
Trang 464.2 Danh sách liên kết đơn (tt)
Trang 474.2 Danh sách liên kết đơn (tt)
4.2.2.g Hủy danh sách (tt)
Cài đặt thuật toán:
void SLLDelete (SLLType &SList)
{
SLLType TempNode = SList;
while (SList != NULL)
{
SList = SList ->NextNode;
TempNode ->NextNode = NULL;
Trang 484.2 Danh sách liên kết đơn (tt)
4.2.2.h Tạo mới danh sách/Nhập danh sách
danh sách mà danh sách ban đầu là rỗng
Trang 494.2 Danh sách liên kết đơn (tt)
4.2.2.h Tạo mới danh sách/Nhập danh sách (tt)
return (SList);
}
Trang 504.2 Danh sách liên kết đơn (tt)
4.2.2.i Tách 1 danh sách thành nhiều danh sách
Trang 514.2 Danh sách liên kết đơn (tt)
4.2.2.j Nhập nhiều danh sách thành 1 danh sách
Trang 524.2 Danh sách liên kết đơn (tt)
4.2.2.k Sắp xếp thứ tự các phần tử trong danh sách
Thuật toán sắp xếp trộn tự nhiên:
B2: SLLMerge(SLList, TempList, SLList)
B3: Lặp lại B1
BKT: Kết thúc
void SLLNaturalMergeSort(SLLType &SList)
{ SLLMerge(SList, TempList, List);
SList = List;
}
return;
}
Trang 534.2 Danh sách liên kết đơn (tt)
4.2.2.h Sao chép 1 danh sách
NewList bằng cách duyệt qua các nút của SLList để lấy thành
phần dữ liệu để tạo thành 1 nút mới & bổ sung nút mới này
vào danh sách NewList
Trang 544.2 Danh sách liên kết đơn (tt)
4.2.2.h Sao chép 1 danh sách (tt)
Cài đặt thuật toán:
SLLType CurrNode = SList;
while (CurrNode != NULL)
if (NewNode == NULL)
break;
}}
return (NewList);
}
Trang 554.3 Danh sách liên kết đôi (DLL)
các phần tử khác trong danh sách
typedef struct DLLNode
Trang 564.3 Danh sách liên kết đôi (tt)
4.3.1 Quản lý danh sách liên kết liên kết đôi:
DLLType DLList1
typedef struct DLLPairNode
Trang 574.3 Danh sách liên kết đôi (tt)
4.3.2 Thao tác trên danh sách liên kết đôi
Trang 584.3 Danh sách liên kết đôi (tt)
4.3.2.a Khởi tạo danh sách liên kết đôi
Cho giá trị các con trỏ quản lý địa chỉ 2 nút đầu và cuối danh sách
liên kết đôi về NULL
Trang 59B3: DNode ->NextNode = NULL
B4: DNode ->Key = NewData
B5: DNode ->PreNode = NULL
BKT: Kết thúc
if (Pnode != NULL)
{ Pnode ->NextNode = NULL;
Pnode ->Key = NewDataPnode ->PreNode = NULL;
}
return (Pnode);
}
Trang 604.3 Danh sách liên kết đôi (tt)
4.3.2.c Thêm 1 phần tử vào danh sách (Thêm đầu)
B4: NewNode ->NextNode = DLLList.DLLFirst
B5: DLLList.DLLFirst ->PreNode = NewNode
// chuyển vai trò đứng đầu của NewNode cho DLLFirst
B6: DLLList.DLLFirst = NewNode
BKT: Kết thúc
Trang 614.3 Danh sách liên kết đôi (tt)
4.3.2.c Thêm 1 phần tử vào danh sách (Thêm đầu)
NewNode ->NextNode = DList.DLLFirst;
DList.DLLFirst ->PreNode = NewNode;
DList.DLLFirst = NewNode;
}
return (NewNode);
}
Trang 624.3 Danh sách liên kết đôi (tt)
4.3.2.c Thêm 1 phần tử vào danh sách (Thêm cuối)
B4: DLLList.DLLLast ->NextNode = NewNode
B5: NewNode ->PreNode = DLLList.DLLLast
// chuyển vai trò đứng đầu của NewNode cho DLLFirst
B6: DLLList.DLLLast = NewNode
BKT: Kết thúc
Trang 634.3 Danh sách liên kết đôi (tt)
4.3.2.c Thêm 1 phần tử vào danh sách (Thêm cuối)
DList.DLLLast ->NextNode = NewNode;
NewNode ->PreNode = DList.DLLLast;
DList.DLLLast = NewNode;
}
return (NewNode);
}
Trang 644.3 Danh sách liên kết đôi (tt)
4.3.2.c Thêm 1 phần tử vào danh sách (Thêm giữa)
B1: IF (InsNode ->NextNode == NULL)
B4: NewNode ->NextNode = InsNode ->NextNode
B5: InsNode ->NextNode ->PreNode = NewNode
B6: InsNode ->NextNode = NewNode
B7: NewNode ->PreNode = InsNode
BKT: Kết thúc
Trang 654.3 Danh sách liên kết đôi (tt)
4.3.2.c Thêm 1 phần tử vào danh sách (Thêm giữa)
&InsNode)
if (NewNode == NULL)
return (NULL);
if (InsNode ->NextNode == NULL)
NewNode ->PreNode = InsNode;
DList.DLLLast = NewNode;
}else
{ NewNode ->NextNode = InsNode ->NextNode;
InsNode ->NextNode ->PreNode = NewNode;
InsNode ->NextNode = NewNode;
NewNode ->PreNode = InsNode;
}
return (NewNode);
}
Trang 664.3 Danh sách liên kết đôi (tt)
4.3.2.d Duyệt qua các nút trong 1 danh sách
Cài đặt thuật toán
while (CurrNode != NULL)
Trang 674.3 Danh sách liên kết đôi (tt)
4.3.2.e Tìm kiếm 1 phần tử trong danh sách
Cài đặt thuật toán
while (CurrNode != NULL)
Trang 684.3 Danh sách liên kết đôi (tt)
4.3.2.f Loại bỏ 1 phần tử trong danh sách
Thuật toán
B1: DelNode = DLLSearching (DLLList DelData) // Tìm kiếm nút DelData
B2: IF(DelNode == NULL)
Thực hiện BKT
B3: IF(DelNode->PreNode=NULL AND DelNode->NextNode=NULL)
B3.1: DLLList.DLLFirst = DLLList.DLLLast = NULL
B3.2: Thực hiện B8
B4: IF (DelNode ->PreNode = NULL) // Loại nút đầu tiên trong DS
B4.1: DLLList.DLLFirst = DLLList.DLLFirst ->NextNode
B4.2: DLLList.DLLFirst ->PreNode = NULL
B4.3: Thực hiện B8
B5: IF (DelNode ->NextNode = NULL) // Loại nút cuối trong DS
B4.1: DLLList.DLLLast = DLLList.DLLLast ->PreNode
B4.2: DLLList.DLLLast ->NextNode = NULL
B4.3: Thực hiện B8
// Liên kết giữa nút trước và sau nút bị xóa
B6: DelNode ->PreNode ->NextNode = DelNode ->NextNode
B7: DelNode ->NextNode ->PreNode = DelNode ->PreNode
// Bỏ mối liên kết giữa DelNode giữa 2 nút trước & sau
B8: DelNode ->NextNode = DelNode ->PreNode = NULL
B9: delete DelNode
Trang 694.3 Danh sách liên kết đôi (tt)
4.3.2.f Loại bỏ 1 phần tử trong danh sách
Cài đặt thuật toán
Int DLLDeleteNode (DLLPType &DList, T DelData)
{ DLLType DelNode = DLLSearching (DList, DelData)
if (DelNode == NULL)
return (-1);
if (DelNode ->NextNode == NULL && DelNode ->PreNode == NULL)
DList.DLLFirst = DList.DLLLast = NULL;
if (DelNode ->NextNode ==NULL) { DList.DLLLast = Dist.DLLLast ->PreNode ; Dist.DLLLast ->NextNode = NULL;
} else { DelNode ->PreNode ->NextNode = DelNode ->NextNode; DelNode ->NextNode ->PreNode = DelNode ->PreNode ; }
}
Trang 704.3 Danh sách liên kết đôi (tt)
4.3.2.g Hủy toàn bộ danh sách
Thực hiện nhiều lần thao tác hủy một nút
B5: DLLList.DLLFirst ->PreNode = NULL
B6: TempNode ->NextNode = NULL
B7: delete TempNode
B8: Lặp lại B1
BKT: Kết thúc