Chúng ta thực hiện thao tác này trong hai trường hợp:
+ Ghép nối đuôi các danh sách lại với nhau;
+ Trộn xen lẫn các phần tử trong các danh sách vào thành một danh sách theo một trật tự nhất định
và sau khi nhập xong vẫn giữ lại các danh sách ban đầu.
Giả sử chúng ta cần nhập hai danh sách DLL_List1 và DLL_List2 lại với nhau thành một danh sách DLL_List.
- Thuật toán ghép nối hai danh sách thành một danh sách mới: B1: DLL_Initialize (DLL_List)
// Đưa DLL_List1 vào đầu DLL_List B2: CurNode = DLL_List1.DLL_First B3: IF (CurNode = NULL)
Thực hiện B7
B4: IF (DLL_Add_Last(DLL_List, CurNode->Key) = NULL) B4.1: DLL_Delete (DLL_List)
B4.2: Thực hiện Bkt
Giáo trình: Cấu Trúc Dữ Liệu và Giải Thuật B6: Lặp lại B3
// Đưa DLL_List2 vào sau DLL_List B7: CurNode = DLL_List2.DLL_First B8: IF (CurNode = NULL)
Thực hiện Bkt
B9: IF (DLL_Add_Last(DLL_List, CurNode->Key) = NULL) B4.1: DLL_Delete (DLL_List)
B4.2: Thực hiện Bkt
B10: CurNode = CurNode->NextNode B11: Lặp lại B8
Bkt: Kết thúc
- Thuật toán trộn 2 danh sách thành 1 danh sách mới theo các đường chạy tự nhiên: B1: CurNode1 = DLL_List1.DLL_First
B2: CurNode2 = DLL_List2.DLL_First
B3: IF (CurNode1 = NULL OR CurNode2 = NULL) Thực hiện B6
B4: IF (CurNode1->Key ≤ CurNode2->Key)
B4.1: If (DLL_Add_Last (DLL_List, CurNode1->Key) = NULL) B4.1.1: DLL_Delete(DLL_List) B4.1.2: Thực hiện Bkt B4.2: CurNode1 = CurNode1->NextNode B4.3: If (CurNode1 = NULL) Thực hiện B10 B4.4: If (CurNode1->PreNode->Key > CurNode1->Key)
B4.4.1: if (DLL_Add_Last (DLL_List, CurNode2->Key) = NULL) B4.4.1.1: DLL_Delete(DLL_List) B4.4.1.2: Thực hiện Bkt B4.4.2: CurNode2 = CurNode2->NextNode B4.4.3: if (CurNode2 = NULL) Thực hiện B6 B4.4.4: if (CurNode2->PreNode->Key > CurNode2->Key) Thực hiện B3 B4.4.5: Lặp lại B4.4.1 B4.5: Lặp lại B4 B5: ELSE
B5.1: If (DLL_Add_Last (DLL_List, CurNode2->Key) = NULL) B5.1.1: DLL_Delete(DLL_List) B5.1.2: Thực hiện Bkt B5.2: CurNode2 = CurNode2->NextNode B5.3: If (CurNode2 = NULL) Thực hiện B6 B5.4: If (CurNode2->PreNode->Key > CurNode2->Key)
B5.4.1: if (DLL_Add_Last (DLL_List, CurNode1->Key) = NULL) B5.4.1.1: DLL_Delete(DLL_List)
Giáo trình: Cấu Trúc Dữ Liệu và Giải Thuật B5.4.2: CurNode1 = CurNode1->NextNode B5.4.3: if (CurNode1 = NULL) Thực hiện B10 B5.4.4: if (CurNode1->PreNode->Key > CurNode1->Key) Thực hiện B3 B5.4.5: Lặp lại B5.4.1 B5.5: Lặp lại B4
// Đưa phần còn lại trong DLL_List1 về DLL_List B6: IF (CurNode1 = NULL)
Thực hiện Bkt
B7: IF (DLL_Add_Last(DLL_List, CurNode1->Key) = NULL) B7.1: DLL_Delete (DLL_List)
B7.2: Thực hiện Bkt
B8: CurNode1 = CurNode1->NextNode B9: Lặp lại B6
// Đưa phần còn lại trong DLL_List2 về DLL_List B10: IF (CurNode2 = NULL)
Thực hiện Bkt
B11: IF (DLL_Add_Last(DLL_List, CurNode2->Key) = NULL) B11.1: DLL_Delete (DLL_List) B11.2: Thực hiện Bkt B12: CurNode2 = CurNode2->NextNode B13: Lặp lại B10 Bkt: Kết thúc - Cài đặt: Các hàm nhập danh sách có prototype:
DLLP_Type DLL_Concat (DLLP_Type &DList1, DLLP_Type &DList2,
DLLP_Type &DList); DLLP_Type DLL_Merge (DLLP_Type &DList1, DLLP_Type &DList2,
DLLP_Type &DList); Hàm thực hiện việc nhập các nút trong hai danh sách DList1, DList2 thành một danh sách theo hai trường hợp đã trình bày trong hai thuật toán trên đây. Hàm trả về giá trị của danh sách sau khi ghép.
Nội dung của các hàm như sau:
DLLP_Type DLL_Concat (DLLP_Type &DList1, DLLP_Type &DList2,
DLLP_Type &DList) { DLL_Initialize (DList);
DLL_Type CurNode = DList1.DLL_First; while (CurNode != NULL)
{ if (DLL_Add_Last (DList, CurNode->Key) == NULL) { DLL_Delete(DList);
return (DList); }
Giáo trình: Cấu Trúc Dữ Liệu và Giải Thuật CurNode = CurNode->NextNode;
}
CurNode = DList2.DLL_First; while (CurNode != NULL)
{ if (DLL_Add_Last (DList, CurNode->Key) == NULL) { DLL_Delete(DList); return (DList); } CurNode = CurNode->NextNode; } return (DList); } //================================================================ DLLP_Type DLL_Merge (DLLP_Type &DList1, DLLP_Type &DList2,
DLLP_Type &DList) { DLL_Type CurNode1 = DList1.DLL_First;
DLL_Type CurNode2 = DList2.DLL_First;
while (CurNode1 != NULL && CurNode2 != NULL) { if (CurNode1->Key <= CurNode2->Key)
{ if (DLL_Add_Last (DList, CurNode1->Key) == NULL) { DLL_Delete (DList); return (DList); } CurNode1 = CurNode1->NextNode; if (CurNode1 == NULL) break; if (CurNode1->PreNode->Key > CurNode1->Key)
do { if (DLL_Add_Last (DList, CurNode2->Key) == NULL) { DLL_Delete (DList);
return (DList); }
CurNode2 = CurNode2->NextNode; }
while (CurNode2 != NULL &&
CurNode2->PreNode->Key <= CurNode2->Key); }
else
{ if (DLL_Add_Last (DList, CurNode2->Key) == NULL) { DLL_Delete (DList); return (DList); } CurNode2 = CurNode2->NextNode; if (CurNode2 == NULL) break; if (CurNode2->PreNode->Key > CurNode2->Key)
do { if (DLL_Add_Last (DList, CurNode1->Key) == NULL) { DLL_Delete (DList);
Giáo trình: Cấu Trúc Dữ Liệu và Giải Thuật return (DList);
}
CurNode1 = CurNode1->NextNode; }
while (CurNode1 != NULL &&
CurNode1->PreNode->Key <= CurNode1->Key); }
}
while (CurNode1 != NULL)
{ if (DLL_Add_Last (DList, CurNode1->Key) == NULL) { DLL_Delete (DList);
break; }
CurNode1 = CurNode1->NextNode; }
while (CurNode2 != NULL)
{ if (DLL_Add_Last (DList, CurNode2->Key) == NULL) { DLL_Delete (DList); break; } CurNode2 = CurNode2->NextNode; } return (DList); }