Tải bản đầy đủ (.pdf) (34 trang)

Báo cáo: Danh sách liên kết pdf

Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (290.09 KB, 34 trang )

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
A
i
A node in a
linked list
A header node
A tail node
2
Các loại danh sách liên kết
•DSLK đơn
•DSLK kép
•DSLK vòng
A
2
A
3
A
N
A
1
A
1


A
2
A
3
A
N
A
1
A
2
A
3
A
N
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
•typedefstruct 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
•typedefstruct 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
•typedefstruct SinhVien
{
char Ten[30];
int MaSV;
}SV;
•typedefstruct 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
•typedefstruct phanso
{
int tu;
int mau;

}PS;
•typedefstruct 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
•typedefstruct
{
NODE* pHead;
NODE* pTail;
} LIST;
pHead
pTail
A
1
A
2
A
3
A
N
DSLK Đơn-Các Tác Vụ
•Khởi tạo DS
void 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 DS
NODE* 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)
A
1
A
2
A
3
A

N
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
A
1
A
2

A
3
A
N
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
A
1
A
2

A
3
A
N
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 DS
NODE * 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 DS
void * 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 tử sau phần tử q
– Xoáphần tử cókhoák
DSLK Đơn-Các Tác Vụ
• Xoáphần tử đầu
A
1
A
2
A
3
A
N
pTail

pHead
12
DSLK Đơn-Các Tác Vụ
• Xoáphần tử đầu
DataRemoveHead(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
A
1
A
2
A
3
A
N
pTail
pHead
q p

13
DSLK Đơn-Các Tác Vụ
• Xoáphần tử sau phần tử q
void 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ák
int 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ách
void 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
typedefstruct DNode

{
T info;
struct DNode* pPre;
struct DNode* pNext;
}DNODE;
15
DSLK Kép-Cấu trúc dữ liệu
DNODE* GetNode(T x)
{
DNODE *p;
p = new DNODE;
if ( p==NULL) return NULL
p ->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-Insert
void 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 q
void 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
56
31
29
179
52
21
Bottom_of_stack
(this is where the
stack started)
top
Empty/unfilled
portion of stack
Direction
in which
stack 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()
typedefstruct {
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;
elsereturn 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;
elsereturn false;
}
20
Stack-Vídụ
56
31
29
179
52
21
top
56
31
29
179
21
pop()
56
31
29
179
2
21
push(2)
56
31

29
179
2
21
Return 2
top
top
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 portion
of the queue
123179 5 63
21
Queue-Tác vụ
•EnQueue()
Input: element to be enqueued
Algorithm:
increment back by 1
add element to the empty location pointed to by back
Return: void
•DeQueue()
Input: void
Algorithm:

return the element pointed to by front
increment front by 1
Return: the element dequeued
Queue –Vídụ
front back
123179 5 63
front back
123179 5 63 17
front back
3179 5 63 17
front back
523179 5 63 17
front back
5279 5 63 17
enqueue(17)
dequeue
enqueue(52)
dequque
22
Queue –Vídụ
front
back
79 5 63 17
front back
5279 5 63 17
enqueue(23)
dequeue
52 23
back
5 63 17 52 23

front
back
63 17 52 23
front
17 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
Ghi chú: back giữ vị tríphần tử có
giữ liệu
front giữ vị tríphần tử không cógiữ
liệu
Circular Queue – ĐK Rỗng
DeQueue-> Queue empty: back == front
24
Circular Queue – ĐK Đầy
EnQueue-> Queue full:
(back +1)%size == front
Circular Queue
typedefstruct {
int size;

int front;
int back;
T* values;
} QUEUE;
25
Circular Queue
void init(QUEUE &q, int size) {
q.size = size;
q.values = new T[size];
q.front = 0;
q.back = 0;
}
Circular Queue
bool isFull(QUEUE q) {
if( (q.back+1) % q.size == q.front) return true;
elsereturn false;
}
bool isEmpty(QUEUE q) {
if(q.back == q.front) return true;
elsereturn false;
}

×