baigiang ctdl
TRANSCRIPT
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
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)
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
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ố
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;
}
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)
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;
} }
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;
} }
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); }
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;
}}
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
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
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;
}
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;
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
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);}
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);}
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;
}
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;
}
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
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
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
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
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;
}
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;
}
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
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
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);
}}
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
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;}
31
BST-Retrieval
x
BST-Insert
• Tạo BSTvới các info: 5 9 7 3 8 12 6 4 20
32
BST-Insert
BST-Insert
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;
}