baigiang ctdl

of 33 /33
1 Danh Sách Liên Kết Nguyn Thanh Hiên Danh Sách Liên Kết (Linked List) •Gm nhiu phn t(gi mi phn tmt node) Các phn tni kết vi nhau thông qua vùng liên kết Các phn tđược try xut tun tvà bao gm: vùng dliu và các vùng liên kết A i A node in a linked list A header node A tail node

Upload: ho-loi

Post on 22-Jan-2018

129 views

Category:

Documents


1 download

TRANSCRIPT

Page 1: Baigiang ctdl

1

Danh Sách Liên Kết

Nguyễn Thanh Hiên

Danh Sách Liên Kết (Linked List)

• Gồm nhiều phần tử (gọi mỗi phần tử làmột node)

• Các phần tử nối kết với nhau thông qua vùng liên kết

• Các phần tử được try xuất tuần tự và bao gồm: vùng dữ liệu và các vùng liên kết

Ai

A node in alinked list

A header nodeA tail node

Page 2: Baigiang ctdl

2

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

• DSLK đơn

• DSLK kép

• DSLK vòng

A2 A3 ANA1

A1 A2 A3 AN

A1 A2 A3 AN

Các Tác Vụ

• Khởi tạo (init)• Kiểm tra DSLK rỗng (IsEmpty)• Xác định kích thước (Size)• Chèn (Insert)• Xóa (Remove)• Tìm kiếm (Retrieve)• Thay thế (Replace)• Duyệt (Traverse)

Page 3: Baigiang ctdl

3

DSLK Đơn- Cấu trúc dữ liệu

• typedef struct node{T info; // T là kiểu đã định nghĩa trước

struct node* link; // con trỏ chỉ đến cấu trúc node

}NODE;

• T là kiểu dữ liệu cơ bản hoặc kiểu dữ liệu tự định nghĩa

DSLK Đơn- Cấu trúc dữ liệu

• typedef struct node{

int info; struct node* link;

}NODE; CTDL cho một phần tử của DS các số nguyên

Page 4: Baigiang ctdl

4

DSLK Đơn- Cấu trúc dữ liệu• typedef struct SinhVien

{char Ten[30]; int MaSV;

}SV; • typedef struct svNode

{SV info; struct svNode* link;

}SVNODE;

CTDL cho một phần tử của DS các sinh viên

DSLK Đơn- Cấu trúc dữ liệu• typedef struct phanso

{int tu; int mau;

}PS; • typedef struct psNode

{PS info; struct psNode* link;

}PSNODE;

CTDL cho một phần tử của DS các phân số

Page 5: Baigiang ctdl

5

DSLK Đơn- Cấu trúc dữ liệu

• typedef struct{

NODE* pHead; NODE* pTail;

} LIST;

pHead

pTail

A1 A2 A3 AN

DSLK Đơn- Các Tác Vụ

• Khởi tạo DSvoid init (LIST &list){

list.pHead=NULL;list.pTail=NULL;

}

Page 6: Baigiang ctdl

6

DSLK Đơn- Các Tác Vụ

• Tạo một Node mới cho DSNODE* getNode(T x){

NODE* p;p=new NODE;if (p==NULL)return NULL;

p-> info = x;p-> link=NULL;return p;

}

x

DSLK Đơn- Các Tác Vụ

• Chèn một phần tử vào DS

– Chèn vào đầu (insertHead)

– Chèn vào cuối (insertTail)

– Chèn sau phần tử q (insertMid)

Page 7: Baigiang ctdl

7

DSLK Đơn- Các Tác Vụ

• Chèn vào đầu (insertHead)

A1 A2 A3 AN

pTail

pHead

x

newNode

(1)(2)

DSLK Đơn- Các Tác Vụ• Chèn vào đầu (insertHead)void insertHead(LIST &ds, NODE* newNode) {

if (ds.pHead==NULL) //ds rỗng {

ds.pHead = newNode; ds.pTail = ds.pHead; } else{

newNode ->link = ds.pHead; ds.pHead = newNode;

} }

Page 8: Baigiang ctdl

8

DSLK Đơn- Các Tác Vụ

• Chèn vào cuối (insertTail)

pHead

pTail

A1 A2 A3 AN

x

(1)

(2)

DSLK Đơn- Các Tác Vụ• Chèn vào cuối (insertTail)void insertTail(LIST &ds, NODE *newNode) {

if (ds.pHead==NULL) {

ds.pHead = newNode; ds.pTail = ds.pHead; } else {

ds.pTail->link = newNode;ds.pTail = newNode;

} }

Page 9: Baigiang ctdl

9

DSLK Đơn- Các Tác Vụ

• Chèn sau phần tử q (insertMid)

pHead

pTail

A1 A2 A3 AN

x

(1)(2)

q

DSLK Đơn- Các Tác Vụ• Chèn sau phần tử q (insertMid)void insertMid(LIST &ds,NODE *q, NODE* newNode) {

if ( q!=NULL) {

newNode ->link = q-> link; q-> link = newNode; if(q == ds.pTail)

ds.pTail = newNode; } else //chèn vào đầu danh sách

insertHead(ds, newNode); }

Page 10: Baigiang ctdl

10

DSLK Đơn- Các Tác Vụ

• Tìm một phần tử trong DSNODE * Retrieve(LIST ds, Data k) {

NODE *p; p = ds.pHead; while((p!= NULL)&&(p->info != x))

p = p->link;return p;

}

DSLK Đơn- Các Tác Vụ• Duyệt DSvoid * Traverse(LIST ds) {

NODE *p; p = ds.pHead; while(p!= NULL){

process(p);p = p->link;

}}

Page 11: Baigiang ctdl

11

DSLK Đơn- Các Tác Vụ

• Xoá một phần tử

– Xoá phần tử đầu

– Xoá phân ftử sau phần tử q

– Xoá phần tử có khoá k

DSLK Đơn- Các Tác Vụ

• Xoá phần tử đầu

A1 A2 A3 AN

pTail

pHead

Page 12: Baigiang ctdl

12

DSLK Đơn- Các Tác Vụ• Xoá phần tử đầuData RemoveHead(LIST &ds) {

NODE *p; Data x = NULLDATA; if ( ds.pHead != NULL) {

p = ds.pHead; x = p->info; ds.pHead = ds.pHead->link; delete p; if(ds.pHead == NULL) ds.pTail = NULL;

} return x;

}

DSLK Đơn- Các Tác Vụ

• Xoá phân ftử sau phần tử q

A1 A2 A3 AN

pTail

pHead

q p

Page 13: Baigiang ctdl

13

DSLK Đơn- Các Tác Vụ• Xoá phần tử sau phần tử qvoid RemoveAfter (LIST &ds, NODE *q) { NODE *p;

if ( q != NULL) {

p = q ->link ; if ( p != NULL) {

if(p == ds.pTail) ds.pTail = q; q->link = p->link; delete p;

} } else

RemoveHead(ds); }

DSLK Đơn- Các Tác Vụ• Xoá phần tử có khoá kint RemoveNode(LIST &ds, Data k) {

NODE *p = ds.pHead; NODE *q = NULL; while( p != NULL) {

if(p->info == k) break; q = p; p = p->link;

} if(p == NULL) return 0;

//Không tìm thấy k

if(q != NULL) {

if(p == ds.pTail) ds.pTail = q;

q->link = p->link; delete p;

} else //p là phần tử đầu ds {

ds.pHead = p->link; if(ds.pHead == NULL)

ds.pTail = NULL; } return 1;

}

Page 14: Baigiang ctdl

14

DSLK Đơn- Hủy danh sáchvoid ReamoveList(LIST &ds) { NODE *p;

while (ds.pHead!= NULL) {

p = ds.pHead; ds.pHead = p->link; delete p;

} ds.pTail = NULL;

}

DSLK Kép- Cấu trúc dữ liệu

typedef struct DNode{

T info;struct DNode* pPre;struct DNode* pNext;

}DNODE;

Page 15: Baigiang ctdl

15

DSLK Kép- Cấu trúc dữ liệuDNODE* GetNode(T x) {

DNODE *p;p = new DNODE; if ( p==NULL) return NULLp ->Info = x; p->pPrev = NULL;p->pNext = NULL;return p;

}

DSLK Kép- Insert

• Chèn đầu • Chèn cuối • Chèn sau phần tử q• Chèn trước phần tử q

Page 16: Baigiang ctdl

16

DSLK Kép- Insert

DSLK Kép- Insertvoid Insert(DLIST &ds, DNODE* q, DNODE* newNode){ DNODE* p = q->pNext;

if ( q!=NULL) {newNode->pNext = p; //(1)newNode->pPrev = q; //(2)q->pNext = newNode; //(3) if(p != NULL)

p->pPrev = newNode; //(4)if(q == ds.pTail)

ds.pTail = newNode;}else //chèn vào đầu danh sách

InsertHead(ds, newNode);}

Page 17: Baigiang ctdl

17

DSLK Kép- Remove

• Xóa đầu • Xóa cuối • Xóa sau phần tử q• Xóa trước phần tử q• Xóa có khóa k

DSLK Kép- Remove sau qvoid Remove(DLIST &ds, DNODE *q){ DNODE *p;

if ( q != NULL){

p = q ->pNext ;if ( p != NULL){

q->pNext = p->pNext;if(p == ds.pTail) ds.pTail = q;else p->pNext->pPrev = q;delete p;

}} else

RemoveHead(ds);}

Page 18: Baigiang ctdl

18

STACK

563129

17952

21 Bottom_of_stack(this is where the stack started)

top

Empty/unfilledportion of stack

Directionin whichstack grows

•Danh sách hạn chế

•Các phần tử được thêm vào và lấy ra ở đỉnh stack

• Hiện thực dùng dslk hoặc array

Stack – Tác vụ

• Init()• Push()• Pop()• IsEmpty()• IsFull()

typedef struct {T *theArray;int top;int size;

}STACK;

void init (STACK &s, int size) {

s.size = size;

s.theArray = new T[size];

s.top = -1;

}

Page 19: Baigiang ctdl

19

Stack- Push()

void push(STACK &s, T x){if (!isFull(s)){

s.top++;s.theArray[s.top]=x;

}}bool isFull(STACK s) { if(s.top < s.size-1) return false;else return true;

}

Stack- Pop(), Top()T pop(STACK &s){

if (!isEmpty(s))return s.theArray[s.top--];

}T top(STACK s){

return s.theArray[s.top];}bool isEmpty(STACK s) {

if(s.top == -1) return true; else return false;

}

Page 20: Baigiang ctdl

20

Stack-Ví dụ

563129

17952

21

top

563129

179

21

pop()

563129

1792

21

push(2)

563129

1792

21

Return 2

toptop

Return 52

top()

Queue

• Danh sách hạn chế• Chèn vào một đầu, lấy ra ở đầu kia• Hiện thực dùng dslk hoặc array • Linear and Circular Queues

front back empty portionof the queue

12 31 79 5 63

Page 21: Baigiang ctdl

21

Queue-Tác vụ

• EnQueue()Input: element to be enqueuedAlgorithm:

increment back by 1add element to the empty location pointed to by back

Return: void• DeQueue()

Input: voidAlgorithm:

return the element pointed to by frontincrement front by 1

Return: the element dequeued

Queue – Ví dụ

front back

12 31 79 5 63

front back12 31 79 5 63 17

front back31 79 5 63 17

front back5231 79 5 63 17

front back5279 5 63 17

enqueue(17)

dequeue

enqueue(52)

dequque

Page 22: Baigiang ctdl

22

Queue – Ví dụ

front back79 5 63 17

front back5279 5 63 17 enqueue(23)

dequeue52 23

back5 63 17 52 23

front

back

63 17 52 23

front17 52 23

front back

dequeue

dequeue

enqueue(44):QUEUE_FULL

Circular Queue

Page 23: Baigiang ctdl

23

Circular Queue

• In enqueue: back = (back +1) mod ARRAY_SIZE

• In dequeue: front = (front + 1) mod ARRAY_SIZE

Circular Queue

back front

1171 57 81 122 39

backfront

8

EnQueue -> Queue full: (back+1)%size == front

DeQueue-> Queue empty: back == front

Page 24: Baigiang ctdl

24

Circular Queue

typedef struct {int size; int front; int back; T* values;

} QUEUE;

Circular Queue

void init(QUEUE &q, int size) { q.size = size; q.values = new T[size]; q.front = 0; q.back = 0;

}

Page 25: Baigiang ctdl

25

Circular Queue

bool isFull(QUEUE q) { if( (q.back+1) % q.size == q.front) return true;else return false;

} bool isEmpty(QUEUE q) {

if(q.back == q.front) return true;else return false;

}

Circular Queuevoid enqueue(QUEUE &q,T x) { if(!isFull(q)) {

q.back = (q.back+1) % q.size; q.values[q.back] = x;

} } T dequeue(QUEUE &q) {

if(!isEmpty(q)) {q.front = (q.front+1) % q.size;return values[q.front];

} return NULLDATA;

}

Page 26: Baigiang ctdl

26

CÂY

A

B C D E F

G H I J K L

T1 T3 T5leaf

root

T2 T4

edge

• Cây N node sẽ có N-1 cạnh

subtree

Path: n1->nk là một chuỗi các nút n1 ->nk sao cho ni là cha ni+1, 1 <= i <=k

depth

CÂY

A

B C D E F

G H I J K L

T1 T3 T5leaf

root

T2 T4

depthCây nhị phân là cây mà mỗi nút có tối đa hai nút con

Page 27: Baigiang ctdl

27

CÂY NHỊ PHÂN

CÁC PHÉP DUYỆT• PreOrder

– Duyệt gốc– Duyệt các cây con bên trái– Duyệt cây con bên phải

• InOrder– Duyệt cây con bên trái– Duyệt gốc – Duyệt cây con bên phải

• PostOrder– Duyệt cây con bên trái – Duyệt cây con bên phải– Duyệt gốc

Page 28: Baigiang ctdl

28

CÂY NHỊ PHÂN- CTDL

typedef struc TNode{ T info; TNode* left; TNode* right;

}TNODE;

TNODE *root=NULL;

CÂY NHỊ PHÂN- Duyệtvoid PreOrder(TNODE *root){

if (root!=NULL){process(root);PreOrder(roo->left);PreOrder(root->right);

}}void InOrder(TNODE *root){

if (root!=NULL){InOrder (root->left);process(root);InOrder (root->right);

}}

void PostOrder(TNODE *root){if (root!=NULL){

PostOrder (root->left);PostOrder (root->right);process(root);

}}

Page 29: Baigiang ctdl

29

VÍ DỤ• Cho cây nhị phân, mỗi nút có info (không trùng

nhau) là một số nguyên– Đếm số nút trên cây– Tính tổng các info trên cây– Cho biết tổ tiên của nút có info là x– Cho biết info các nút ở mức 3– Cho biết tổng info trên cây– Cho biết các nút có tổng info các conlà bội số của info

của cha nó– Cho biết tổng số nút lá– Cho biết tổng số nút bậc một– Cho biết cây có bị suy biến không

LAN TRUYỀN THÔNG TIN

• Tham số– Tham biến – Tham trị

• Hỏi-đápHỏi

aHỏi

b

a, b

Page 30: Baigiang ctdl

30

CÂY NHỊ PHÂN TÌM KIẾM (BST)

BST-RetrievalTNODE* Retrieval(TNODE* root, T x){

if (root != NULL) {

If (root->info==x) return root;

if (x < root->info) return Retrieveal (root->left, x);

else

return Retrieveal (root->right, x);

}

return NULL;}

Page 31: Baigiang ctdl

31

BST-Retrieval

x

BST-Insert

• Tạo BSTvới các info: 5 9 7 3 8 12 6 4 20

Page 32: Baigiang ctdl

32

BST-Insert

BST-Insert

Page 33: Baigiang ctdl

33

BST-Insert

BST-Insertint Insert(TNODE*& root, T x) {

if (root != NULL) {if (root->info==x) return 0;if (x < root ->info)

return Insert(root ->left, x); else

return Insert(root ->right, x);}root = new TNODE; If (root==NULL) return -1root ->right = NULL; root ->left = NULL: root ->info = x; return 1;

}