Danh sách liên kết

Preview:

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

Danh sách liên kết

1

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

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:

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ế:

?

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

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

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

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

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

10

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

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

11

Phần tử trên 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; };

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;

};

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;

};

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; };

};

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.

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:

18

Cấu tạo của 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

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

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

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

23

Create an empty linked list

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

Create an empty linked list

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

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

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

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

Insert Node to a Linked List (cont.)

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

29

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Remove Node from a Linked List (cont.)

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

44

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 …

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

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

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

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;

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

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

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

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

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

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

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

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

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

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

Recommended