59
Danh sách liên kết 1

Danh sách liên kết

  • Upload
    elden

  • View
    56

  • Download
    3

Embed Size (px)

DESCRIPTION

Danh sách liên kết. Giới thiệu. Mảng : Cấu trúc dữ liệu quen thuộc. Tập có thứ tự. Số lượng phần tử cố định (tĩnh). Cấp phát vùng nhớ liên tục. Truy xuất phần tử thông qua chỉ số. Giới thiệu. Đánh giá thao tác trên mảng :. Truy xuất phần tử ? Cập nhật ? Chèn phần tử ? - PowerPoint PPT Presentation

Citation preview

Page 1: Danh sách liên kết

Danh sách liên kết

1

Page 2: Danh sách liên kết

2

Tập có thứ tự. Số lượng phần tử cố định (tĩnh). Cấp phát vùng nhớ liên tục. Truy xuất phần tử thông qua chỉ số.

Giới thiệu

Mảng: Cấu trúc dữ liệu quen thuộc

Page 3: Danh sách liên kết

3

Truy xuất phần tử ? Cập nhật ? Chèn phần tử ? Xóa phần tử ?

Giới thiệu

Đánh giá thao tác trên mảng:

Page 4: Danh sách liên kết

4

không xác định chính xác số lượng phần tử Danh sách bệnh nhân tăng/giảm. Danh sách sinh viên tăng/giảm

Vùng nhớ thay đổi trong quá trình sử dụng. Không đủ vùng nhớ cấp phát liên tục.

Cấu trúc dữ liệu động đáp ứng nhu cầu trên.

Giới thiệu

Thực tế:

?

Page 5: Danh sách liên kết

5

Danh sách liên kết là một tập dữ liệu tuần tự mà mỗi phần tử(element) chứa vị trí của phần tử tiếp theo. element = data + link Ví dụ:

Khái Niệm danh sách liên kết

Page 6: Danh sách liên kết

6

Danh sách liên kết đơn. Danh sách liên kết kép. Danh sách liên kết vòng.

Các loại danh sách liên kết

Page 7: Danh sách liên kết

7

Mỗi phần tử có một liên kết đến phần tử phía sau nó.

Danh sách liên kết đơn

Page 8: Danh sách liên kết

8

Mỗi phần tử có hai liên kế đến phần tử đứng trước và sau nó.

Danh sách liên kết kép

Page 9: Danh sách liên kết

9

Là danh sách liên kết đơn và có mối liên kết giữa phần tử cuối và phần tử đầu.

Danh sách liên kết vòng

Page 10: Danh sách liên kết

10

Phần tử = dữ liệu + liên kết

Phần tử trên danh sách liên kết

Page 11: Danh sách liên kết

11

Phần tử trên danh sách liên kết

Page 12: Danh sách liên kết

12

Cài đặt

Phần tử có dữ liệu gồm 1 thành phần

struct NODE{

dataType number;// dataType là kdl của number

NODE * pNext; };

Page 13: Danh sách liên kết

13

Cài đặt

Phần tử có dữ liệu gồm 3 thành phần

struct NODE {

data type name;datatype id;dataType number;NODE * pNext;

};

Page 14: Danh sách liên kết

14

Cài đặt

Phần tử có dữ liệu gồm 3 thành phần

Ví dụ name kiểu char, id kiểu int, number kiểu float, ta có cấu trúc như sau: struct NODE {

char name[50];int id;float number;NODE * pNext;

};

Page 15: Danh sách liên kết

15

Cài đặt

Phần tử có dữ liệu gồm một cấu trúc

struct DATA struct NODE { {

char name[50]; DATA data;int id; NODE *pNext;float number; };

};

Page 16: Danh sách liên kết

16

Tổ chức danh sách liên kết

Mỗi danh sách liên kết bao gồm: Con trỏ đến phần tử đầu (hoặc/và cuối ) danh sách

o Con trỏ đến phần tử đầu: pHeado Con trỏ đến phần tử cuối: pTail

(Các) phần tử trên danh sách:o Dữ liệuo Các mối liên kết

Lưu ý: pHead, pTail không phải là một nút, nó chỉ là con trỏ chỉ đến nút.

Page 17: Danh sách liên kết

17

Tổ chức danh sách liên kết

Ví dụ: quản lý bằng con trỏ đầu:

Ví dụ quản lý bằng con trỏ đầu và cuối:

Page 18: Danh sách liên kết

18

Cấu tạo của danh sách liên kết

Page 19: Danh sách liên kết

Quản lý danh sách bằng con trỏ đầu

struct LIST{

NODE *pHead;

int Count;

};

Quản lý danh sách bằng con trỏ đầu và cuối

struct LIST{

NODE *pHead;

NODE *pTail;

int Count; // số nút trong danh sách có thể ko cần nếu ko dùng

};

04/21/23 19Bộ môn KHMT - Khoa CNTT - Trường ĐH Tôn Đức Thắng

Cấu tạo của danh sách liên kết

Page 20: Danh sách liên kết

List // Linked Implementation of List (for Singly Linked List) head <pointer> count <integer> // number of elements (optional).End List

Singly Linked List

head

head

data link

20

head

count

An empty Singly Linked List having only head.

An empty Singly Linked List having head and count.

0

Signly linked list

Page 21: Danh sách liên kết

Tạo lập danh sách rỗngKiểm tra danh sách rỗngKiểm tra số phần tử trong danh sáchThêm một nút vào danh sáchXóa một nút khỏi danh sáchDuyệt danh sáchTìm một phần tử

04/21/23 21Bộ môn KHMT - Khoa CNTT - Trường ĐH Tôn Đức Thắng

Các thao tác trên DSLK Đơn

Page 22: Danh sách liên kết

Before After

List having head

List having head and count

head ? headhead = NULL

head

count = ?

? head

count = 0head = NULL count = 0

22

Create an empty linked list

Page 23: Danh sách liên kết

23

Create an empty linked list

Page 24: Danh sách liên kết

04/21/23 24Bộ môn KHMT - Khoa CNTT - Trường ĐH Tôn Đức Thắng

Create an empty linked list

Page 25: Danh sách liên kết

Tạo lập danh sách rỗng

04/21/23 25Bộ môn KHMT - Khoa CNTT - Trường ĐH Tôn Đức Thắng

?

Count pHead

? list

Trước khi tạo lập

0

Count pHead

list

Sau khi tạo lập

void InitList(LIST &L){

L.Count = 0;L.pHead = NULL;

}

Lưu ý:Luôn luôn khởi tạo danh sách rỗng trước khi sử dụng

Create an empty linked list

Page 26: Danh sách liên kết

Kiểm tra danh sách rỗng

Kiểm tra số phần tử trong danh sách

04/21/23 26Bộ môn KHMT - Khoa CNTT - Trường ĐH Tôn Đức Thắng

int IsEmptyList(LIST L){

if(L.pHead == NULL)return 1;

return 0;}

int CountNode(LIST L){

return L.Count;}

Check linked list

Page 27: Danh sách liên kết

1. Allocate memory for the new node and set up data.2. Locate the pointer p in the list, which will point to the

new node: If the new node becomes the first element in the List: p

is head.

Otherwise: p is pPre->link, where pPre points to the predecessor of the new node.

27

head

pNewx

pPre

pNew

head

x

Insert Node to a Linked List

Page 28: Danh sách liên kết

3. Update pointers: Point the new node to its successor. Point the pointer p to the new node.

28

head

X

pNew

X

pNew->link = pPre->link (1)

pPre->link = pNew (2)pPre

(1)(2)

pNew->link = head (1)

head= pNew (2)

X

head

pNew

X

(1)(2)

Insert Node to a Linked List

Page 29: Danh sách liên kết

Insert Node to a Linked List (cont.)

Insertion is successful when allocation memory for the new node is successful.

29

Page 30: Danh sách liên kết

Insert Node to a Linked List (cont.)There is no difference between

insertion in the middle (a) and insertion at the end of the list (b)

(a)

(b)

30

head

X

pNew

X

pNew->link = pPre->link (1)

pPre->link = pNew (2)pPre

(1)(2)

pPre

pNew

head

x

Page 31: Danh sách liên kết

Insert Node to a Linked List (cont.)There is no difference between

insertion at the beginning of the list (a) and insertion

to an empty list (b).

(a)

(b)

31

pNew

head

pNew

pNew->link = head (1)head= pNew (2)

X

head

pNew

X

(1)(2)

head

Page 32: Danh sách liên kết

Insert Algorithm<ErrorCode> Insert (val DataIn <DataType>)// For ordered list.Inserts a new node in a singly linked list.

Pre DataIn contains data to be insertedPost If list is not full, DataIn has been inserted;

otherwise, list remains unchanged.Return success or overflow.

32

Page 33: Danh sách liên kết

InsertNode Algorithm (cont.)<ErrorCode> Insert (val DataIn <dataType>)1. Allocate pNew2. if (memory overflow)

1. return overflow3. else

1. pNew->data = DataIn2. Locate pPre // pPre remains NULL if Insertion at the

beginning or to an empty list3. if (pPre = NULL) // Adding at the beginning or to an

empty list1. pNew->link = head2. head = pNew

4. else // Adding in the middle or at the end of the list1. pNew->link = pPre->link2. pPre->link = pNew

5. return successend Insert

33

Page 34: Danh sách liên kết

Trước khi thêm

Sau khi thêm

04/21/23 34Bộ môn KHMT - Khoa CNTT - Trường ĐH Tôn Đức Thắng

1 15

Count pHead

99

pNew

(1)

(2)

pNew

Count pHead

152 99

Thêm một node vào đầu danh sách

Page 35: Danh sách liên kết

Thêm một nút vào đầu DS (quản lý bằng con trỏ đầu)Nếu danh sách rỗng thì L.pHead = pNewNgược lại:

pNew pNext = L.pHead L.pHead = pNew

void AddFirst( LIST &L , NODE * pNew){

if(L.pHead == NULL)

L.pHead = pNew;

else {

pNew pNext = L.pHead;

L.pHead = pNew;

}

}

04/21/23 35Bộ môn KHMT - Khoa CNTT - Trường ĐH Tôn Đức Thắng

Các thao tác trên danh sách liên kết đơn

Cách 1

Cách 1.1

Page 36: Danh sách liên kết

Thêm một nút vào đầu DS (quản lý bằng con trỏ đầu)

void AddFirst( LIST &L , datatype x)

{

NODE * pNew = new NODE;

pNew data = x;

pNew pNext = NULL;

if(L.pHead == NULL)

L.pHead = pNew;

else

{

pNew pNext = L.pHead;

L.pHead = pNew;

}

}

04/21/23 36Bộ môn KHMT - Khoa CNTT - Trường ĐH Tôn Đức Thắng

Các thao tác trên danh sách liên kết đơn

Cách 1.2

Page 37: Danh sách liên kết

Thêm một nút vào đầu DS (quản lý bằng con trỏ đầu và cuối)Nếu danh sách rỗng thì L.pHead = L.pTail = pNewNgược lại:

pNew pNext = L.pHead L.pHead = pNew

void AddFirst( LIST &L , NODE * pNew) {

if(L.pHead == NULL)

L.pHead = L.pTail = pNew;

else {

pNew pNext = L.pHead;

L.pHead = pNew;

}

}

04/21/23 37Bộ môn KHMT - Khoa CNTT - Trường ĐH Tôn Đức Thắng

Các thao tác trên danh sách liên kết đơn

Cách 2

Page 38: Danh sách liên kết

Thêm một nút vào giữa DS. Sau nút pRev (ql bằng con trỏ đầu) Trước khi thêm

Sau khi thêm

04/21/23 38Bộ môn KHMT - Khoa CNTT - Trường ĐH Tôn Đức Thắng

Các thao tác trên danh sách liên kết đơn

992 15

50

pNew

(1)

pPrev (2)

503 15 99

pPrev pNew

Count pHead

Count pHead

Page 39: Danh sách liên kết

Thêm một nút vào giữa DS. Sau nút pRev(quản lý bằng con trỏ đầu )

void AddMid( LIST &L, NODE *pRev , NODE * pNew)

{

pNew pNext = pRev pNext;

pRev pNext = pNew;

}

void AddMid( LIST &L , NODE *pRev , DataType x)

{

NODE *pNew = new NODE;

pNew data = x;

pNew pNext = NULL;

pNew pNext = pRev pNext;

pRev pNext = pNew;

}

04/21/23 39Bộ môn KHMT - Khoa CNTT - Trường ĐH Tôn Đức Thắng

Các thao tác trên danh sách liên kết đơn

Cách 1

Cách 2

Page 40: Danh sách liên kết

Thêm 1 nút vào giữa DS. Sau nút pRev(ql bằng con trỏ đầu và cuối )

void AddMid( LIST &L, NODE *pRev , NODE * pNew)

{ pNew pNext = pRev pNext;

pRev pNext = pNew;

if(pRev == L.pTail)

L.pTail = pNew;

}

void AddMid( LIST &L, NODE *pRev , Datatype x)

{ NODE *pNew = new NODE;

pNew data =x;

pNew pNext = NULL;

pNew pNext = pRev pNext;

pRev pNext = pNew;

if(pRev == L.pTail)

L.pTail = pNew;

}

04/21/23 40Bộ môn KHMT - Khoa CNTT - Trường ĐH Tôn Đức Thắng

Các thao tác trên danh sách liên kết đơn

Cách 1

Cách 2

Page 41: Danh sách liên kết

Thêm 1 nút cuối DSLK Nếu DS rỗng thì L.pHead = L.pTail = pNew Ngược lại:

L.pTail pNext = Pnew L.pTail = pNew

04/21/23 41Bộ môn KHMT - Khoa CNTT - Trường ĐH Tôn Đức Thắng

Các thao tác trên danh sách liên kết đơn

992 15

pTail

Count pHead

50

pNew (1)

(2)

992 15

pPrev

Count pHead

50

L.pTail pNext = pNewL.pTail = pNew

Page 42: Danh sách liên kết

Remove Node from a Linked List1. Locate the pointer p in the list which points to

the node to be deleted (pDel will hold the node

to be deleted). If that node is the first element in the List: p is

head.

Otherwise: p is pPre->link, where pPre points to the predecessor of the node to be deleted.

42

pPre pDel

pDel

head

head

Page 43: Danh sách liên kết

Remove Node from a Linked List (cont.)2. Update pointers: p points to the successor of

the node to be deleted.

3. Recycle the memory of the deleted node.

head

pDel

X

head

pDelX

pPre

head = pDel->link

Recycle pDel

pPre->link = pDel->link

Recycle pDel

43

Page 44: Danh sách liên kết

Remove Node from a Linked List (cont.)

Removal is successful when the node to be deleted is found.

44

Page 45: Danh sách liên kết

Remove Node from a Linked List (cont.)

There is no difference between

Removal a node from the middle (a) and removal a node from the end (b) of the list.

(a)

(b)

45

head

pDel

X

pPre

head …

pDelpPre

pPre->link = pDel->link

Recycle pDel

pDel

X

pPrehead …

Page 46: Danh sách liên kết

Remove Node from a Linked List (cont.)

There is no difference between

removal the node from the beginning (a) of the list and removal the only-remained node in the list (b).

(a)

(b)

46

head

pDel

head

pDel

head

pDelX

head = pDel->link

Recycle pDel

Page 47: Danh sách liên kết

RemoveNode Algorithm<ErrorCode> Remove (ref DataOut <DataType>)

Removes a node from a singly linked list.

Pre DataOut contains the key need to be removed.

Post If the key is found, DataOut will contain the data corresponding to it, and that node has been removed from the list; otherwise, list remains unchanged.

Return success or failed.

47

Page 48: Danh sách liên kết

RemoveNode Algorithm (cont.)<ErrorCode> Remove (ref DataOut <DataType>)1. Allocate pPre, pDel // pPre remains NULL if the node to be

deleted is at the beginning of the list or is the only node.2. if (pDel is not found)

1. return failed3. else

1. DataOut = pDel->data2. if (pPre = NULL) // Remove the first node or the only node

1. head = pDel->link3. else // Remove the node in the middle or at the end of the

list1. pPre->link = pDel->link

4. recycle pDel5. return success

end Remove48

Page 49: Danh sách liên kết

Xóa một nút ở đầu DS

Trước khi xóa

Sau khi xóa

04/21/23 49Bộ môn KHMT - Khoa CNTT - Trường ĐH Tôn Đức Thắng

Các thao tác trên danh sách liên kết đơn

(1)

992 15

pCurr Count pHead

1 99

Count pHead

(2)

L.pHead = pCurr pNext;delete pCurr;

Page 50: Danh sách liên kết

Xóa một nút ở đầu DS (ql bằng con trỏ đầu) Nếu pHead != NULL thì

Lấy nút ở đầu DS (pCurr) ra để xóa Tách pCurr ra khỏi danh sách Delete pCurr

Void DeleteFirst(LIST &L)

{

NODE *pCurr;

if(L.pHead != NULL)

{

pCurr = L.pHead;

L.pHead = L.pHead pNext;// L.pHead=pCurr->pNext

delete pCurr;

}

}

04/21/23 50Bộ môn KHMT - Khoa CNTT - Trường ĐH Tôn Đức Thắng

Các thao tác trên danh sách liên kết đơn

Page 51: Danh sách liên kết

Xóa một nút ở đầu DS (ql bằng con trỏ đầu và cuối) Nếu pHead != NULL thì

Lấy nút ở đầu DS (pCurr) ra để xóa Tách nút ở đầu DS (pCurr) ra khỏi danh sách Delete pCurr

Nếu pHead = NULL thì pTail = NULL: Xâu rỗngVoid DeleteFirst(LIST &L)

{

NODE *pCurr;

if(L.pHead != NULL)

{

pCurr = L.pHead;

L.pHead = L.pHead pNext;

delete pCurr;

}

if(L.pHead == NULL)

L.pTail = NULL;

}

04/21/23 51Bộ môn KHMT - Khoa CNTT - Trường ĐH Tôn Đức Thắng

Các thao tác trên danh sách liên kết đơn

Page 52: Danh sách liên kết

Xóa 1 nút ở giữa DS. Sau nút pRev (ql bằng con trỏ đầu)Trước khi xóa

Sau khi xóa

04/21/23 52Bộ môn KHMT - Khoa CNTT - Trường ĐH Tôn Đức Thắng

Các thao tác trên danh sách liên kết đơn

503 15 99

pCurrpPrev

2 15 99

pPrev

Count pHead

Count pHead

pPrev pNext = pCurr pNextDelete pCurr

Page 53: Danh sách liên kết

Xóa 1 nút ở giữa DS. Sau nút pRev (ql bằng con trỏ đầu)Void DeleteAfter_pPrev(LIST & L, NODE * pPrev)

{

NODE * pCurr;

pCurr = pPrev pNext;// lấy nút sau pPrev ra để xóa

pPrev pNext =pCurr pNext;

delete pCurr;

}

04/21/23 53Bộ môn KHMT - Khoa CNTT - Trường ĐH Tôn Đức Thắng

Các thao tác trên danh sách liên kết đơn

Page 54: Danh sách liên kết

Xóa 1 nút ở giữa DS. Sau nút pRev (ql bằng con trỏ đầu và cuối)Int DeleteAfter_pPrev(LIST & L, NODE * pPrev)

{

NODE * pCurr;

if(pPrev == L.pTail)

return 0;

pCurr = pPrev pNext;

pPrev pNext =pCurr pNext;

delete pCurr;

if(pPrev pNext == NULL)

L.pTail = pPrev;

}

04/21/23 54Bộ môn KHMT - Khoa CNTT - Trường ĐH Tôn Đức Thắng

Các thao tác trên danh sách liên kết đơn

Page 55: Danh sách liên kết

Xóa 1 nút trong DS ( tổng quát)void DeleteNode(LIST & L, NODE * pPrev, NODE * PCurr)

{

if(pPrev == NULL) // xóa nút đầu

L.pHead =pCurr pNext;

else // Xóa nút giữa

pPrev pNext =pCurrpNext;

delete pCurr;

L.count --;

}

04/21/23 55Bộ môn KHMT - Khoa CNTT - Trường ĐH Tôn Đức Thắng

Các thao tác trên danh sách liên kết đơn

Page 56: Danh sách liên kết

Duyệt DSLK Đơn: là đi từ đầu DSLK cho đến cuối DSLK

Để đi từ đầu DSLK đến cuối DSLK ta sử dụng một biến con trỏ NODE để lần lượt giữ địa chỉ các NODE trong DSLK.

void PrintList( LIST L)

{

NODE * pCurr = L.pHead;

while( pCurr != NULL)

{

cout << pCurr data;

pCurr = pCurr pNext;

}

}

04/21/23 56Bộ môn KHMT - Khoa CNTT - Trường ĐH Tôn Đức Thắng

Các thao tác trên danh sách liên kết đơn

Page 57: Danh sách liên kết

Duyệt DSLK Đơn: sử dụng vòng lặp for

void PrintList( LIST L)

{

for(NODE * pCurr = L.pHead; pCur; pCurr pNext)

{

cout << pCurr data;

pCurr = pCurr pNext;

}

}

04/21/23 57Bộ môn KHMT - Khoa CNTT - Trường ĐH Tôn Đức Thắng

Các thao tác trên danh sách liên kết đơn

pCurr !=NULL

Page 58: Danh sách liên kết

Tìm một phần tửDuyệt tuần tự từ đầu danh sáchNếu gặp nút chứa khóa cần tìm Stop và

thông báo tìm thấyNếu đi đến cuối danh sách Stop và thông

báo không tìm thấyChi phí O(n)

04/21/23 58Bộ môn KHMT - Khoa CNTT - Trường ĐH Tôn Đức Thắng

Các thao tác trên danh sách liên kết đơn

Page 59: Danh sách liên kết

o Tìm một phần tử

NODE * FindNode(LIST L, DataType key )

{

NODE * pCurr = L.pHead;// bđ từ đầu DS

while(pCurr != NULL)

{

if(pCurr data == key)

return pCurr; // tìm Thấy

pCurr = pCurr pNext;// chuyển đến nút kế

}

return NULL;// không tìm thấy

}

04/21/23 59

Bộ môn KHMT - Khoa CNTT - Trường ĐH Tôn Đức Thắng

Các thao tác trên danh sách liên kết đơn