danh sách liên kết ( list )
DESCRIPTION
Danh sách liên kết ( List ). Danh saùch keà : - PowerPoint PPT PresentationTRANSCRIPT
1
DanhDanh sáchsách liênliên kếtkết ( (ListList) ) a.a. Danh saùch keà :Danh saùch keà :
Caùc phaàn töû cuûa danh saùch goïi laø caùc node, Caùc phaàn töû cuûa danh saùch goïi laø caùc node, ñöôïc löu tröõ keà lieàn nhau trong boä nhôù. Moãi ñöôïc löu tröõ keà lieàn nhau trong boä nhôù. Moãi node coù theå laø moät giaù trò kieåu int, float, node coù theå laø moät giaù trò kieåu int, float, char, … hoaëc coù theå laø moät struct vôùi nhieàu char, … hoaëc coù theå laø moät struct vôùi nhieàu vuøng tin. Maûng hay chuoãi laø daïng cuûa danh vuøng tin. Maûng hay chuoãi laø daïng cuûa danh saùch keà.saùch keà.
Ñòa chæ cuûa moãi node trong danh saùch ñöôïc Ñòa chæ cuûa moãi node trong danh saùch ñöôïc xaùc ñònh baèng chæ soá (index). Chæ soá cuûa xaùc ñònh baèng chæ soá (index). Chæ soá cuûa danh saùch laø moät soá nguyeân vaø ñöôïc ñaùnh danh saùch laø moät soá nguyeân vaø ñöôïc ñaùnh töø 0 ñeán moät giaù trò toái ña naøo ñoù.töø 0 ñeán moät giaù trò toái ña naøo ñoù.
Danh saùch keà laø caáu truùc döõ lieäu tónh, soá Danh saùch keà laø caáu truùc döõ lieäu tónh, soá node toái ña cuûa danh saùch keà coá ñònh sau khi node toái ña cuûa danh saùch keà coá ñònh sau khi caáp phaùt neân soá node caàn duøng coù khi thöøa caáp phaùt neân soá node caàn duøng coù khi thöøa hay thieáu. Ngoaøi ra danh saùch keà khoâng phuø hay thieáu. Ngoaøi ra danh saùch keà khoâng phuø hôïp vôùi caùc thao taùc thöôøng xuyeân nhö theâm hôïp vôùi caùc thao taùc thöôøng xuyeân nhö theâm hay xoùa phaàn töû treân danh saùch,hay xoùa phaàn töû treân danh saùch,
2
DanhDanh sáchsách liênliên kếtkết ( (ListList) ) b.b. Danh saùch lieân keát :Danh saùch lieân keát :
Caùc phaàn töû cuûa danh saùch goïi laø node, Caùc phaàn töû cuûa danh saùch goïi laø node, naèm raûi raùc trong boä nhôù. Moãi node, ngoaøi naèm raûi raùc trong boä nhôù. Moãi node, ngoaøi vuøng döõ lieäu thoâng thöôøng, coøn coù vuøng vuøng döõ lieäu thoâng thöôøng, coøn coù vuøng lieân keát chöùa ñòc chæ cuûa node keá tieáp hay lieân keát chöùa ñòc chæ cuûa node keá tieáp hay node tröôùc noù.node tröôùc noù.
Danh saùch lieân keát laø caáu truùc döõ lieäu Danh saùch lieân keát laø caáu truùc döõ lieäu ñoäng, coù theå theâm hay huûy node cuûa danh ñoäng, coù theå theâm hay huûy node cuûa danh saùch trong khi chay chöông trình. Vôùi caùch caøi saùch trong khi chay chöông trình. Vôùi caùch caøi ñaët caùc thao taùc theâm hay huûy node ta chæ ñaët caùc thao taùc theâm hay huûy node ta chæ caàn thay ñoåi laïi vuøng lieân keát cho phuø hôïp.caàn thay ñoåi laïi vuøng lieân keát cho phuø hôïp.
Tuy nhieân, vieäc löu tröõ danh saùch lieân keát Tuy nhieân, vieäc löu tröõ danh saùch lieân keát toán boä nhôù hôn anh saùch keà vì moãi node cuûa toán boä nhôù hôn anh saùch keà vì moãi node cuûa danh saùch phaûi chöùa theâm vuøng lieân keát. danh saùch phaûi chöùa theâm vuøng lieân keát. Ngoaøi ra vieäc truy xuaát node thöù I trong danh Ngoaøi ra vieäc truy xuaát node thöù I trong danh saùch lieân keát chaäm hôn vì phaûi duyeät töø saùch lieân keát chaäm hôn vì phaûi duyeät töø ñaàu danh saùch.ñaàu danh saùch.
3
CóCó nhiềunhiều kiểukiểu tổtổ chứcchức liênliên kếtkết giữagiữa cáccác phầnphần tửtử trongtrong danhdanh sáchsách nhưnhư : :
DanhDanh sáchsách liênliên kếtkết đơnđơn DanhDanh sáchsách liênliên kếtkết képkép DanhDanh sáchsách liênliên kếtkết vòngvòng ……
DanhDanh sáchsách liênliên kếtkết ( (ListList) )
4
DanhDanh sáchsách liênliên kếtkết ( (ListList) ) DanhDanh sáchsách liênliên kếtkết đơnđơn:: mỗimỗi phầnphần tửtử liênliên kếtkết vớivới phầnphần
tửtử đứngđứng sausau nónó trongtrong danhdanh sáchsách::
DanhDanh sáchsách liênliên kếtkết képkép:: mỗimỗi phầnphần tửtử liênliên kếtkết vớivới cáccác phầnphần tửtử đứngđứng trướctrước vàvà sausau nónó trongtrong danhdanh sáchsách::
A B X Z Y
A B C D
5
DanhDanh sáchsách liênliên kếtkết ( (ListList) ) DanhDanh sáchsách liênliên kếtkết vòngvòng : : phầnphần tửtử cuốicuối danhdanh sáchsách liênliên
kếtkết vớivới phầnphần tửtử đầuđầu danhdanh sáchsách::
A B X Z Y
A B C D
SắpSắp xếp trênxếp trên danhdanh sách sách
liên kết đơnliên kết đơn
7
SắpSắp xếpxếp danhdanh sáchsách
CáchCách tiếptiếp cậncận::
Phương án 1:Phương án 1:
Hoán vị nội dung các phần tử trong danh sách Hoán vị nội dung các phần tử trong danh sách (thao tác trên vùng data).(thao tác trên vùng data).
Phương án 2 :Phương án 2 :
Thay đổi các mối liên kết (thao tác trên vùng Thay đổi các mối liên kết (thao tác trên vùng link)link)
8
SắpSắp xếpxếp danhdanh sáchsáchHoánHoán vịvị nộinội dungdung cáccác phầnphần tửtử trongtrong danhdanh sáchsách
CàiCài đặtđặt lạilại trêntrên danh sách liên kếtdanh sách liên kết mộtmột trongtrong nhữngnhững thuậtthuật toántoán sắpsắp xếpxếp đãđã biếtbiết trêntrên mảngmảng
ĐiểmĐiểm kháckhác biệtbiệt duyduy nhấtnhất làlà cáchcách thứcthức truytruy xuấtxuất đếnđến cáccác phầnphần tửtử trêntrên danh sách liên kếtdanh sách liên kết thôngthông quaqua liênliên kếtkết thaythay vìvì chỉchỉ sốsố nhưnhư trêntrên mảngmảng. .
DoDo thựcthực hiệnhiện hoánhoán vịvị nộinội dungdung củacủa cáccác phầnphần tửtử nênnên đòiđòi hỏihỏi sửsử dụngdụng thêmthêm vùngvùng nhớnhớ trungtrung giangian chỉchỉ thíchthích hợphợp vớivới cáccác xâuxâu cócó cáccác phầnphần tửtử cócó thànhthành phầnphần datadata kíchkích thướcthước nhỏnhỏ. .
KhiKhi kíchkích thướcthước củacủa trườngtrường datadata lớnlớn, , việcviệc hoánhoán vịvị giágiá trịtrị củacủa haihai phânphân tửtử sẽsẽ chiếmchiếm chichi phíphí đángđáng kểkể. .
9
voidvoid SLL_InterChangeSort SLL_InterChangeSort ( ( ListList &l ) &l )
{{
for for ( ( NodeNode* p=l.first ; p!=* p=l.first ; p!=l.lastl.last ; p=p->link ) ; p=p->link )
for for ( ( NodeNode* q=p->link ; q!=* q=p->link ; q!=NULLNULL ; q=q- ; q=q->link )>link )
if if ( p->data > q->data )( p->data > q->data )
SwapSwap( p->data , q->data );( p->data , q->data );
} }
Sắp xếp bằng phương pháp đôi chô trưc tiếp ( Interchange Sort )
10
12 2 8 1 5
p
q
l.first
l.last
Sắp xếp đôi chô trưc tiếp
( Interchange Sort )
11
1 12 8 2 5
p
q
l.first
l.last
Sắp xếp đôi chô trưc tiếp
( Interchange Sort )
12
1 2 12 8 5
p
q
l.first
l.last
Sắp xếp đôi chô trưc tiếp
( Interchange Sort )
13
1 2 5 12 8
p
q
l.first
l.last
Sắp xếp đôi chô trưc tiếp
( Interchange Sort )
14
1 2 5 8 12
p
q
Dưng
l.first
l.last
Sắp xếp đôi chô trưc tiếp
( Interchange Sort )
15
Sắp xếp bằng phương pháp chọn trưc tiếp Sắp xếp bằng phương pháp chọn trưc tiếp
( ( Selection sortSelection sort ) )
void ListSelectionSort (LIST &l)
{
for ( Node* p = l.first ; p != l.last ; p = p->link )
{
Node* min = p;
for ( Node* q = p->link ; q != NULL ; q = q->link )
if ( min->data > q->data ) min = q ;
Swap(min->data, p->data);
}
}
16
12 2 8 1 5
p
min
l.first
l.last
Sắp xếp bằng phương pháp chọn trưc tiếp Sắp xếp bằng phương pháp chọn trưc tiếp ( ( Selection sortSelection sort ) )
17
1 2 8 12 5
p
min
l.first
l.last
Sắp xếp bằng phương pháp chọn trưc tiếpSắp xếp bằng phương pháp chọn trưc tiếp ( ( Selection sortSelection sort ) )
18
1 2 8 12 5
p
min
l.first
l.last
Sắp xếp bằng phương pháp chọn trưc tiếp Sắp xếp bằng phương pháp chọn trưc tiếp ( ( Selection sortSelection sort ) )
19
1 2 5 12 8
p
min
l.first
l.last
Sắp xếp bằng phương pháp chọn trưc tiếpSắp xếp bằng phương pháp chọn trưc tiếp ( ( Selection sortSelection sort ) )
20
1 2 5 8 12
p
min
l.first
l.last
Dưng
Sắp xếp bằng phương pháp chọn trưc tiếpSắp xếp bằng phương pháp chọn trưc tiếp ( ( Selection sortSelection sort ) )
21
void void SLL_BubleSortSLL_BubleSort ( ( ListList l ) l ){{
NodeNode* t = * t = l.lastl.last ; ;forfor ( ( NodeNode* p = * p = l.first l.first ; p != ; p != NULLNULL ; p = p->link) ; p = p->link){{ NodeNode* t1;* t1;
forfor ( ( NodeNode* q=* q=l.firstl.first ; p!=t ; q=q->link ) ; p!=t ; q=q->link ){{
ifif( q->data ( q->data >> q->link->data ) q->link->data )SwapSwap( q->data ( q->data ,, q->link->data ); q->link->data );
t1 = q ;t1 = q ;}}t = t1;t = t1;
}}}}
Sắp xếp bằng phương pháp nôi bọtSắp xếp bằng phương pháp nôi bọt ( ( BubbleBubble sortsort ) )
22
12 2 8 1 5
q
q->link
l.first
l.last
Sắp xếp bằng phương pháp nôi bọtSắp xếp bằng phương pháp nôi bọt ( ( Bubble sortBubble sort ) )
23
2 8 1 5 12
q
q->link
l.first
l.last
Sắp xếp bằng phương pháp nôi bọtSắp xếp bằng phương pháp nôi bọt ( ( Bubble sortBubble sort ) )
24
2 1 5 8 12
q
q->link
l.first
l.last
Sắp xếp bằng phương pháp nôi bọtSắp xếp bằng phương pháp nôi bọt ( ( Bubble sortBubble sort ) )
25
1 2 5 8 12
q
q->link
l.first
l.last
Sắp xếp bằng phương pháp nôi bọtSắp xếp bằng phương pháp nôi bọt ( ( Bubble sortBubble sort ) )
26
1 2 5 8 12l.first
l.last
Dưng
Sắp xếp bằng phương pháp nôi bọtSắp xếp bằng phương pháp nôi bọt ( ( Bubble sortBubble sort ) )
27
SắpSắp xếpxếp ThayThay đôiđôi cáccác mốimối liênliên kếtkết
Thay vì hoán đổi giá trị, ta sẽ tìm cách thay đổi trình tự móc Thay vì hoán đổi giá trị, ta sẽ tìm cách thay đổi trình tự móc nối của các phần tử sao cho tạo lập nên được thứ tự mong nối của các phần tử sao cho tạo lập nên được thứ tự mong muốn muốn chỉ thao tác trên các móc nối (link). chỉ thao tác trên các móc nối (link).
Kích thước của trường link:Kích thước của trường link: Không phụ thuộc vào bản chất dữ liệu lưu trong xâu Không phụ thuộc vào bản chất dữ liệu lưu trong xâu Bằng kích thước 1 con trỏ (2 hoặc 4 byte trong môi Bằng kích thước 1 con trỏ (2 hoặc 4 byte trong môi
trường 16 bit, 4 hoặc 8 byte trong môi trường 32 bit…)trường 16 bit, 4 hoặc 8 byte trong môi trường 32 bit…) Thao tác trên các móc nối thường phức tạp hơn thao tác trực Thao tác trên các móc nối thường phức tạp hơn thao tác trực
tiếp trên dữ liệu.tiếp trên dữ liệu.Cần cân nhắc khi chọn cách tiếp cận: Nếu dữ liệu không quá Cần cân nhắc khi chọn cách tiếp cận: Nếu dữ liệu không quá
lớn thì nên chọn phương án 1 hoặc một thuật toán hiệu quả lớn thì nên chọn phương án 1 hoặc một thuật toán hiệu quả nào đó.nào đó.
28
Phương pháp lấy Phương pháp lấy NodeNode ra khỏi danh ra khỏi danh sách giữ nguyên địa chỉ của sách giữ nguyên địa chỉ của NodeNode
12 2 5 1
q
8
p
1 . q->link = p->link ; // p->link chứa địa chỉ sau p
2 . q->link = NULL ; // p không liên kết phần tử Node
29
Quick Sort : Thuật toánQuick Sort : Thuật toán //input: xâu (first, last)//input: xâu (first, last)//output: xâu đã được sắp tăng dần//output: xâu đã được sắp tăng dần Bước 1: Nếu xâu có ít hơn 2 phần tửBước 1: Nếu xâu có ít hơn 2 phần tử
Dừng;Dừng; //xâu đã có thứ tự//xâu đã có thứ tự Bước 2: Chọn X là phần tử đầu xâu L làm ngưỡng. Trích X ra Bước 2: Chọn X là phần tử đầu xâu L làm ngưỡng. Trích X ra
khỏi L.khỏi L. Bước 3: Tách xâu L ra làm 2 xâu LBước 3: Tách xâu L ra làm 2 xâu L11 (gồm các phần tử nhỏ hơn (gồm các phần tử nhỏ hơn
hay bằng X) và Lhay bằng X) và L22 (gồm các phần tử lớn hơn X). (gồm các phần tử lớn hơn X). Bước 4: Sắp xếp Bước 4: Sắp xếp Quick SortQuick Sort (L (L11).). Bước 5: Sắp xếp Bước 5: Sắp xếp Quick SortQuick Sort (L (L22).). Bước 6: Nối LBước 6: Nối L11, X, và L, X, và L22 lại theo trình tự ta có xâu L đã được lại theo trình tự ta có xâu L đã được
sắp xếp.sắp xếp.
30
SắpSắp xếpxếp quickquick sortsort
first
6
8
2
4
5
1
31
QuickQuick sort sort : : phânphân hoạchhoạch
first
6
8
2
4
5
1
X
Chọn phần tử đầu xâu làm ngưỡng
32
QuickQuick sort sort : : phânphân hoạchhoạch
first
6
8
2
4
5
1
X
Tách xâu hiện hành thành 2 xâu
first1
first2
33
QuickQuick sort sort : : phânphân hoạchhoạch
first
6
8
2
4
5
1
X
Tách xâu hiện hành thành 2 xâu
first1
first2
34
QuickQuick sort sort : : phânphân hoạchhoạch
first
6
8
2
4
5
1
X
Tách xâu hiện hành thành 2 xâu
first1
first2
35
QuickQuick sort sort : : phânphân hoạchhoạch
first
6
8
2
4
5
1
X
Tách xâu hiện hành thành 2 xâu
first1
first2
36
QuickQuick sortsort
first
6
8
2
4
5
1
X
Sắp xếp các xâu l1, l2
first1
first2
37
QuickQuick sortsort
first
6
8
2
4
5
1
X
Nối l1, X, l2first
1
first2
Đưa kết quả vào first
38
void SListAppend(SLIST &l, LIST &l2){if (l2.first == NULL) return; if (l.first == NULL)
l = l2;else {
l.first->link = l2.first;l.last = l2.last;
} Init(l2);
}
Nối 2 danh sáchNối 2 danh sách
39
void SListQSort(SLIST &l) {NODE *X, *p;SLIST l1, l2;if (list.first == list.last) return; Init(l1); Init(l2);X = l.first; l.first=x->link;while (l.first != NULL) {
p = l.first;if (p->data <= X->data) AddFirst(l1, p);else AddFirst(l2, p);
}SListQSort(l1); SListQSort(l2);SListAppend(l, l1);AddFirst(l, X);SListAppend(l, l2);
}
40
NhậnNhận xétxét:: QuickQuick sortsort trêntrên xâuxâu đơnđơn đơnđơn giảngiản hơnhơn phiênphiên bảnbản củacủa
nónó trêntrên mảngmảng mộtmột chiềuchiều KhiKhi dùngdùng quickquick sortsort sắpsắp xếpxếp mộtmột xâuxâu đơnđơn, , chỉchỉ cócó mộtmột
chọnchọn lựalựa phầnphần tửtử cầmcầm canhcanh duyduy nhấtnhất hợphợp lýlý làlà phầnphần tửtử đầuđầu xâuxâu. . ChọnChọn bấtbất kỳkỳ phầnphần tửtử nàonào kháckhác cũngcũng làmlàm tăngtăng chichi phíphí mộtmột cáchcách khôngkhông cầncần thiếtthiết dodo cấucấu trúctrúc tựtự nhiênnhiên củacủa xâuxâu..
QuickQuick sort sort : : nhậnnhận xétxét
Stack ( Ngăn xếp )Stack ( Ngăn xếp )Queue Queue ( ( HàngHàng đợi đợi ))
StackStack
43
StackStack
StackStack làlà mộtmột vậtvật chứachứa ( (containercontainer) ) cáccác đốiđối tượngtượng làmlàm việcviệc theotheo cơcơ chếchế LIFOLIFO ( (LastLast InIn FirstFirst OutOut) ) ViệcViệc thêmthêm mộtmột đốiđối tượngtượng vàovào stackstack hoặchoặc lấylấy mộtmột đốiđối tượngtượng rara khỏikhỏi stackstack đượcđược thựcthực hiệnhiện theotheo cơcơ chếchế ““Vào sau raVào sau ra trước”trước”. .
CácCác đốiđối tượngtượng cócó thểthể đượcđược thêmthêm vàovào stackstack bấtbất kỳkỳ lúclúc nàonào nhưngnhưng chỉchỉ cócó đốiđối tượngtượng thêmthêm vàovào sausau cùngcùng mớimới đượcđược phépphép lấylấy rara khỏikhỏi stackstack. .
““Push”Push”: : ThaoThao táctác thêmthêm 1 1 đốiđối tượngtượng vàovào stackstack ““Pop”Pop”: : ThaoThao táctác lấylấy 1 1 đốiđối tượngtượng rara khỏikhỏi stackstack.. StackStack cócó nhiềunhiều ứngứng dụngdụng: : khửkhử đệđệ quiqui, , tổtổ chứcchức lưulưu vếtvết cáccác
quáquá trìnhtrình tìmtìm kiếmkiếm theotheo chiềuchiều sâusâu vàvà quayquay luilui, , vétvét cạncạn, , ứngứng dụngdụng trongtrong cáccác bàibài toántoán tínhtính toántoán biểubiểu thứcthức, , ……
44
GiGiới thiệuới thiệu LIFO: Last In First OutLIFO: Last In First Out Thao tác Pop, Push chỉ diễn ra ở 1 đầuThao tác Pop, Push chỉ diễn ra ở 1 đầu
45
HiHiện thưc stackện thưc stack((Implementation of a StackImplementation of a Stack ) )
Mảng 1 chiều Danh sách LK
Kích thước stack khi quá thiếu, lúc
quá thừa
Cấp phát động!
Push / Pop hơi phức tạp
Push/Pop khá dễ dàng
46
Stack ( Ngăn xếp )Stack ( Ngăn xếp ) StackStack làlà mộtmột CTDLCTDL trừutrừu tượngtượng tuyếntuyến tínhtính hỗhỗ trợtrợ 2 2 thaothao
táctác chínhchính:: PushPush((oo):): ThêmThêm đốiđối tượngtượng oo vàovào đầuđầu stackstack PopPop():(): LấyLấy đốiđối tượngtượng ởở đầuđầu stackstack rara khỏikhỏi stackstack
vàvà trảtrả vềvề giágiá trịtrị củacủa nónó. . NếuNếu stackstack rỗngrỗng thìthì lỗilỗi sẽsẽ xảyxảy rara..
StackStack cũngcũng hỗhỗ trợtrợ mộtmột sốsố thaothao táctác kháckhác:: isEmptyisEmpty(): (): KiểmKiểm tratra xemxem stackstack cócó rỗngrỗng khôngkhông.. TopTop(): (): TrảTrả vềvề giágiá trịtrị củacủa phầnphần tửtử nằmnằm ởở đầuđầu stackstack
màmà khôngkhông hủyhủy nónó khỏikhỏi stackstack. . NếuNếu stackstack rỗngrỗng thìthì lỗilỗi sẽsẽ xảyxảy rara..
47
BiểuBiểu diễndiễn StackStack dùngdùng mảngmảng((Array Implementation of a Stack)Array Implementation of a Stack)
CóCó thểthể tạotạo mộtmột stackstack bằngbằng cáchcách khaikhai báobáo mộtmột mảngmảng 1 1 chiềuchiều vớivới kíchkích thướcthước tốitối đađa làlà NN ( (víví dụdụ: : NN =1000). =1000).
StackStack cócó thểthể chứachứa tốitối đađa NN phầnphần tửtử đánhđánh sốsố từtừ 0 0 đếnđến NN--1. 1.
PhầnPhần tửtử nằmnằm ởở đầuđầu stackstack sẽsẽ cócó chỉchỉ sốsố toptop ( (lúclúc đóđó trongtrong stackstack đangđang chứachứa top top +1 +1 phầnphần tửtử))
ĐểĐể khaikhai báobáo mộtmột stackstack, , tata cầncần mộtmột mảngmảng 1 1 chiềuchiều SS, , biếnbiến nguyênnguyên tt chocho biếtbiết chỉchỉ sốsố củacủa đầuđầu stackstack vàvà hằnghằng sốsố NN chocho biếtbiết kíchkích thướcthước tốitối đađa củacủa stackstack..
Data S [N];int top;
48
BiểuBiểu diễndiễn StackStack dùngdùng mảngmảng
LệnhLệnh toptop = 0 = 0 sẽsẽ tạotạo rara mộtmột stackstack SS rỗngrỗng. . GiáGiá trịtrị củacủa top+1top+1 sẽsẽ chocho biếtbiết sốsố phầnphần tửtử hiệnhiện
hànhhành cócó trongtrong stackstack.. KhiKhi càicài đặtđặt bằngbằng mảngmảng 1 1 chiềuchiều, , stackstack cócó kíchkích
thướcthước tốitối đađa nênnên cầncần xâyxây dựngdựng thêmthêm mộtmột thaothao táctác phụphụ chocho stackstack::FullFull(): (): KiểmKiểm tratra xemxem stackstack cócó đầyđầy chưachưa..KhiKhi stackstack đầyđầy, , việcviệc gọigọi đếnđến hàmhàm pushpush() () sẽsẽ
phátphát sinhsinh rara lỗilỗi..
49
Khai báo stackKhai báo stacktypedef structtypedef struct node node{{
intint data; data;};};
typedef structtypedef struct stack stack{{
intint top; top;nodenode list[N]; list[N];
};};
50
Khởi tạo Stack:Khởi tạo Stack:
voidvoid InitInit((stackstack &s) &s)
{{
s.top=0;s.top=0;
}}
Biểu diễn Stack dùng mảngBiểu diễn Stack dùng mảng
51
BiểuBiểu diễndiễn StackStack dùngdùng mảngmảng KiểmKiểm tratra stackstack rỗngrỗng hayhay khôngkhông
int Empty(stack s){
if(s.top==0)
return 1;
return 0;
}
52
BiểuBiểu diễndiễn StackStack dùngdùng mảngmảng KiểmKiểm tratra stackstack đầyđầy hayhay khôngkhông
int Full(stack s){
if(s.top==N-1)
return 1;
return 0;}
53
BiểuBiểu diễndiễn StackStack dùngdùng mảngmảng
ThêmThêm mộtmột phầnphần tửtử xx vàovào stackstack SS void Push(stack &s,node x)
{
if(!Full(s)) // stack chưa đầy
s.list[++s.top]=x;
}
54
BiểuBiểu diễndiễn StackStack dùngdùng mảngmảng TríchTrích thôngthông tintin vàvà huỷhuỷ phầnphần tửtử ở ở đỉnhđỉnh stackstack SS
node Pop(stack &s){
node n;if(!Empty(s)) // stack khác r?ng{
n=s.list[s.top];s.top--;
}return n;
}
55
BiểuBiểu diễndiễn StackStack dùngdùng mảngmảng
NhậnNhận xétxét::CácCác thaothao táctác trêntrên đềuđều làmlàm việcviệc vớivới chichi phíphí
OO(1).(1).ViệcViệc càicài đặtđặt stackstack thôngthông quaqua mảngmảng mộtmột chiềuchiều
đơnđơn giảngiản vàvà khákhá hiệuhiệu quảquả..TuyTuy nhiênnhiên, , hạnhạn chếchế lớnlớn nhấtnhất củacủa phươngphương ánán
càicài đặtđặt nàynày làlà giớigiới hạnhạn vềvề kíchkích thướcthước củacủa stackstack NN. . GiáGiá trịtrị củacủa NN cócó thểthể quáquá nhỏnhỏ soso vớivới nhunhu cầucầu thựcthực tếtế hoặchoặc quáquá lớnlớn sẽsẽ làmlàm lãnglãng phíphí bộbộ nhớnhớ..
56
BiểuBiểu diễndiễn StackStack dùngdùng danhdanh sáchsách liênliên kếtkết((Implementation of a Stack Using Implementation of a Stack Using Linked Representation)Linked Representation)
CóCó thểthể tạotạo mộtmột stackstack bằngbằng cáchcách sửsử dụngdụng mộtmột danhdanh sáchsách liênliên kếtkết đơnđơn ( (DSLKDSLK). ).
DSLKDSLK cócó nhữngnhững đặcđặc tínhtính rấtrất phùphù hợphợp đểđể dùngdùng làmlàm stackstack vìvì mọimọi thaothao táctác trêntrên stackstack đềuđều diễndiễn rara ởở đầuđầu stackstack..
stackstack *s;
57
Khai báo stackKhai báo stacktypedef structtypedef struct node node{{
intint data; data;node *link;node *link;
};};typedef structtypedef struct stack stack{{
nodenode *top; *top;};};
58
BiểuBiểu diễndiễn StackStack dùngdùng danhdanh sáchsách liênliên kếtkết
Khôûi taïo stackKhôûi taïo stack
void void InitInit((stackstack &t) &t)
{{
t.top=NULL;t.top=NULL;
}}
59
BiểuBiểu diễndiễn StackStack dùngdùng danhdanh sáchsách liênliên kếtkết
KiểmKiểm tratra stackstack rỗngrỗng : : int Empty(stack t)
{
return t.top == NULL ? 1 : 0; // stack rỗng
}
60
ThêmThêm mộtmột phầnphần tửtử xx vàovào stackstack SS voidvoid PushPush(stack &t, int x){(stack &t, int x){
nodenode *p= *p=newnew node; node;
ifif(p!=NULL){(p!=NULL){
p->data=x;p->data=x;
p->link=NULL;p->link=NULL;
ifif((EmptyEmpty(t))(t))
t.top=p;t.top=p;
elseelse{{
p->link=t.top;p->link=t.top;
t.top=p;t.top=p;
}}
}}
}}
61
•Trích thông tin và huỷ phần tử ở đỉnh stack STrích thông tin và huỷ phần tử ở đỉnh stack S
intint PopPop(stack &t)(stack &t){{
nodenode *p; *p;int x;int x;ifif(!(!EmptyEmpty(t)) (t)) {{
p=t.top;p=t.top;t.top=p->link;t.top=p->link;x=p->data;x=p->data;delete p;delete p;returnreturn x; x;
}}
}}
62
ỨngỨng dụngdụng củacủa StackStack StackStack thíchthích hợphợp lưulưu trữtrữ cáccác loạiloại dữdữ liệuliệu màmà trìnhtrình tựtự
truytruy xuấtxuất ngượcngược vớivới trìnhtrình tựtự lưulưu trữtrữ MộtMột sốsố ứngứng dụngdụng củacủa StackStack: :
TrongTrong trìnhtrình biênbiên dịchdịch ( (thôngthông dịchdịch), ), khikhi thựcthực hiệnhiện cáccác thủthủ tụctục, , StackStack đượcđược sửsử dụngdụng đểđể lưulưu môimôi trườngtrường củacủa cáccác thủthủ tụctục..
LưuLưu dữdữ liệuliệu khikhi giảigiải mộtmột sốsố bàibài toántoán củacủa lýlý thuyếtthuyết đồđồ thịthị ( (nhưnhư tìmtìm đườngđường điđi))
KhửKhử đệđệ quiqui ......
63
ỨngỨng dụngdụng củacủa StackStack VíVí dudu::ïï thủthủ tụctục QuickQuick__SortSort dùngdùng StackStack đểđể khửkhử đệđệ quiqui:: 1.1. l l:=1; :=1; rr:=:=nn;; 2.2. Chọn Chọn phầnphần tửtử giữagiữa xx:=:=aa[([(ll++rr) ) divdiv 2]; 2]; 3.3. Phân Phân hoạchhoạch ( (ll,,rr) ) thànhthành ( (ll1,1,rr1) 1) vàvà ( (ll2,2,rr2) 2) bằngbằng cáchcách xétxét: :
yy thuộcthuộc ( (ll1,1,rr1) 1) nếunếu yyxx;; yy thuộcthuộc ( (ll2,2,rr2) 2) ngượcngược lạilại;;
4.4. Nếu Nếu phânphân hoạchhoạch ( (ll2,2,rr2) 2) cócó nhiềunhiều hơnhơn 1 1 phầnphần tửtử thựcthực hiệnhiện: : CấtCất ( (ll2,2,rr2) 2) vàovào StackStack;; NếuNếu ( (ll1,1,rr1) 1) cócó nhiềunhiều hơnhơn 1 1 phầnphần tửtử thựcthực hiệnhiện: :
ll==ll1;1; rr==rr1;1; GotoGoto 2; 2;
NgượcNgược lạilại LấyLấy ( (ll,,rr) ) rara khỏikhỏi StackStack nếunếu StackStack kháckhác rỗngrỗng vàvà GotoGoto 2; 2; NếuNếu khôngkhông dừngdừng;;
HàngHàng đợiđợi ( ( QueueQueue) )
65
HàngHàng đợiđợi ( ( QueueQueue)) HàngHàng đợiđợi làlà mộtmột vậtvật chứachứa ( (containercontainer) ) cáccác đốiđối
tượngtượng làmlàm việcviệc theotheo cơcơ chếchế FIFOFIFO ( (FirstFirst InIn FirstFirst OutOut) ) việcviệc thêmthêm mộtmột đốiđối tượngtượng vàovào hànghàng đợiđợi hoặchoặc lấylấy mộtmột đốiđối tượngtượng rara khỏikhỏi hànghàng đợiđợi đượcđược thựcthực hiệnhiện theotheo cơcơ chếchế “Vào“Vào trướctrước rara trước”trước”..
CácCác đốiđối tượngtượng cócó thểthể đượcđược thêmthêm vàovào hànghàng đợiđợi bấtbất kỳkỳ lúclúc nàonào nhưngnhưng chỉchỉ cócó đốiđối tượngtượng thêmthêm vàovào đầuđầu tiêntiên mớimới đượcđược phépphép lấylấy rara khỏikhỏi hànghàng đợiđợi..
66
HàngHàng đợiđợi ( ( QueueQueue))
67
Giới thiệuGiới thiệu FIFOFIFO Thêm vào cuối và lấy ra ở đầuThêm vào cuối và lấy ra ở đầu
TrongTrong tintin họchọc, , CTDLCTDL hànghàng đợiđợi cócó nhiềunhiều ứngứng dụngdụng: : khửkhử đệđệ quiqui, , tổtổ chứcchức lưulưu vếtvết cáccác quáquá trìnhtrình tìmtìm kiếmkiếm theotheo chiềuchiều rộngrộng vàvà quayquay luilui, , vétvét cạncạn, , tổtổ chứcchức quảnquản lýlý vàvà phânphân phốiphối tiếntiến trìnhtrình trongtrong cáccác hệhệ điềuđiều hànhhành, , tổtổ chứcchức bộbộ đệmđệm bànbàn phímphím, , ……
68
HàngHàng đợiđợi ( ( QueueQueue)) HàngHàng đợiđợi hỗhỗ trợtrợ cáccác thaothao táctác::
EnQueue((oo):):ThêmThêm đốiđối tượngtượng oo vàovào cuốicuối hànghàng đợiđợi
DeQueue(): (): LấyLấy đốiđối tượngtượng ởở đầuđầu queuequeue rara khỏikhỏi hànghàng đợiđợi vàvà trảtrả vềvề giágiá trịtrị củacủa nónó. . NếuNếu hànghàng đợiđợi rỗngrỗng thìthì lỗilỗi sẽsẽ xảyxảy rara..
Empty(): (): KiểmKiểm tratra xemxem hànghàng đợiđợi cócó rỗngrỗng khôngkhông..
Front(): (): TrảTrả vềvề giágiá trịtrị củacủa phầnphần tửtử nằmnằm ởở đầuđầu hànghàng đợiđợi màmà khôngkhông hủyhủy nónó. . NếuNếu hànghàng đợiđợi rỗngrỗng thìthì lỗilỗi sẽsẽ xảyxảy rara..
69
BiểuBiểu diễndiễn QueueQueue dùngdùng mảngmảng
CóCó thểthể tạotạo mộtmột hànghàng đợiđợi bằngbằng cáchcách sửsử dụngdụng mộtmột mảngmảng 1 1 chiềuchiều vớivới kíchkích thướcthước tốitối đađa làlà NN ( (víví dụdụ, , NN=1000) =1000) theotheo kiểukiểu xoayxoay vòngvòng ( (coicoi phầnphần tửtử anan-1-1 kềkề vớivới phầnphần tửtử aa00) ) HàngHàng đợiđợi chứachứa tốitối đađa NN phầnphần tửtử. .
PhầnPhần tửtử ởở đầuđầu hànghàng đợiđợi ( (frontfront elementelement) ) sẽsẽ cócó chỉchỉ sốsố ff. .
PhầnPhần tửtử ởở cuốicuối hànghàng đợiđợi ( (rearrear elementelement) ) sẽsẽ cócó chỉchỉ sốsố rr . .
70
Dùng một array: Có xu hướng dời về cuối arrayDùng một array: Có xu hướng dời về cuối array Hai cách hiện thực đầu tiên:Hai cách hiện thực đầu tiên:
Khi lấy một phần tử ra thì đồng thời dời hàng lên một vị trí.Khi lấy một phần tử ra thì đồng thời dời hàng lên một vị trí.
Chỉ dời hàng về đầu khi cuối hàng không còn chỗChỉ dời hàng về đầu khi cuối hàng không còn chỗ
A B C D B C D B C D E
Ban đầu Lấy ra 1 phần tử:dời tất cả về trước
Thêm vào 1 phần tử
A B C D B C D B C D E
Ban đầu Lấy ra 1 phần tử Thêm vào 1 phần tử: dời tất cả về trước để trống chỗ thêm vào
Biểu diễn Queue dùng mảngBiểu diễn Queue dùng mảng
71
BiểuBiểu diễndiễn QueueQueue dùngdùng mảngmảng
ĐểĐể khaikhai báobáo mộtmột hànghàng đợiđợi, , tata cầncần: : mộtmột mảngmảng mộtmột chiềuchiều QQ, , haihai biếnbiến nguyênnguyên ff, , rr chocho biếtbiết chỉchỉ sốsố củacủa đầuđầu vàvà cuốicuối
củacủa hànghàng đợiđợi hằnghằng sốsố NN chocho biếtbiết kíchkích thướcthước tốitối đađa củacủa hànghàng đợiđợi. .
NgoàiNgoài rara, , khikhi dùngdùng mảngmảng biểubiểu diễndiễn hànghàng đợiđợi, , cầncần dùngdùng mộtmột giágiá trịtrị đặcđặc biệtbiệt, , kýký hiệuhiệu làlà NULLDATANULLDATA, , đểđể gángán chocho nhữngnhững ôô còncòn trốngtrống trêntrên hànghàng đợiđợi. . GiáGiá trịtrị nàynày làlà mộtmột giágiá trịtrị nằmnằm ngoàingoài miềnmiền xácxác địnhđịnh củacủa dữdữ liệuliệu lưulưu trongtrong hànghàng đợiđợi....
72
BiểuBiểu diễndiễn QueueQueue dùngdùng mảngmảng
TrạngTrạng tháithái hànghàng đợiđợi lúclúc bìnhbình thườngthường: :
TrạngTrạng tháithái hànghàng đợiđợi lúclúc xoayxoay vòngvòng::
73
BiểuBiểu diễndiễn QueueQueue dùngdùng mảngmảng HàngHàng đợiđợi cócó thểthể đượcđược khaikhai báobáo cụcụ thểthể nhưnhư sausau::
typedef struct node
{
int data;
};
typedef struct queue
{
int front, rear;
node list[N];
}; DoDo khikhi càicài đặtđặt bằngbằng mảngmảng mộtmột chiềuchiều, , hànghàng đợiđợi cócó kíchkích thướcthước tốitối
đađa nênnên cầncần xâyxây dựngdựng thêmthêm mộtmột thaothao táctác phụphụ chocho hànghàng đợiđợi:: Full(): (): KiểmKiểm tratra xemxem hànghàng đợiđợi cócó đầyđầy chưachưa..
74
BiểuBiểu diễndiễn QueueQueue dùngdùng mảngmảng
TạoTạo hànghàng đợiđợi rỗngrỗng void Init(queue &q)
{
q.front = q.rear = 0;
}
Kiểm tra queue rỗng
int Empty(queue q)
{
if(q.front == q.rear == 0)
return 1;
return 0;
}
75
BiểuBiểu diễndiễn QueueQueue dùngdùng mảngmảng
KiểmKiểm tratra hànghàng đợiđợi đầyđầy hayhay khôngkhôngint Full(queue q)
{
if( q.front== 0 && q.rear== N-1) return 1;
if( q.front == q.rear+1) return 1;
return 0;
}
76
BiểuBiểu diễndiễn QueueQueue dùngdùng mảngmảng
ThêmThêm mộtmột phầnphần tửtử xx vàovào cuốicuối hànghàng đợiđợi QQ void EnQueue(queue &q, node x)
{
if(!Full(q)) //Queue chưa đầy
{
if( q.rear==N-1) q.rear=0;
else q.rear++;
q.list[q.rear]=x;
}
}
77
BiểuBiểu diễndiễn QueueQueue dùngdùng mảngmảng
TríchTrích, , huỷhuỷ phầnphần tửtử ở ở đầuđầu hànghàng đợiđợi QQ node DeQueue(queue &q){
if(!Empty(q)) {
node t=q.list[q.front];if(q.fornt == N -1) q.front = 0;
else q.front++;return t;
}}
78
BiểuBiểu diễndiễn hànghàng đợiđợi dùngdùng danhdanh sáchsách liênliên kếtkết
CóCó thểthể tạotạo mộtmột hànghàng đợiđợi sửsử dụngdụng mộtmột DSLKDSLK đơnđơn. . PhầnPhần tửtử đầuđầu DSKLDSKL ( (headhead) ) sẽsẽ làlà phầnphần tửtử đầuđầu hànghàng đợiđợi, ,
phầnphần tửtử cuốicuối DSKLDSKL ( (tailtail) ) sẽsẽ làlà phầnphần tửtử cuốicuối hànghàng đợiđợi..
a1 a2 aN-2 an-1
Ñaàu haøng
Cuoái haøng
a0
79
typedef structtypedef struct node node
{{
intint data; data;
nodenode *link; *link;
};};
typedef structtypedef struct queue queue
{{
nodenode *front, *rear; *front, *rear;
};};
Biểu diễn hàng đợi Biểu diễn hàng đợi dùng danh sách liên kếtdùng danh sách liên kết
80
Tạo hàng đợi rỗng:Tạo hàng đợi rỗng: void Init(queue &q){q.front=q.rear= NULL;
}}
Kiểm tra hàng đợi rỗng :Kiểm tra hàng đợi rỗng : int Empty(queue &q){ if (q.front == NULL) return 1; // hàng đợi rỗngelse return 0;
}
81
Thêm một phần tử p vào cuối hàng đợiThêm một phần tử p vào cuối hàng đợi void EnQueue(queue &q, node *new_ele){if(q.front == NULL){
q.front=new_ele;q.rear=new_ele;
}else{
q.rear->link=new_ele;q.rear=new_ele;
}}
82
TríchTrích phầnphần tửtử ở ở đầuđầu hànghàng đợiđợi node* DeQueue(queue &q)
{
if (!Empty(q))
{
node *p=q.front;
q.front=p->link;
return p
}
}
Biểu diễn hàng đợi Biểu diễn hàng đợi dùng danh sách liên kếtdùng danh sách liên kết
83
BiểuBiểu diễndiễn hànghàng đợiđợi dùngdùng danhdanh sáchsách liênliên kếtkết NhậnNhận xétxét::
CácCác thaothao táctác trêntrên hànghàng đợiđợi biểubiểu diễndiễn bằngbằng danhdanh sáchsách liênliên kếtkết làmlàm việcviệc vớivới chichi phíphí OO(1). (1).
NếuNếu khôngkhông quảnquản lýlý phầnphần tửtử cuốicuối xâuxâu, , thaothao táctác Dequeue sẽsẽ cócó độđộ phứcphức tạptạp OO((nn).).
84
ỨngỨng dụngdụng củacủa hànghàng đợiđợi
HàngHàng đợiđợi cócó thểthể đượcđược sửsử dụngdụng trongtrong mộtmột sốsố bàibài toántoán:: BàiBài toántoán ‘sản‘sản xuấtxuất vàvà tiêutiêu thụ’thụ’ ( (ứngứng dụngdụng trongtrong cáccác hệhệ
điềuđiều hànhhành songsong songsong).). BộBộ đệmđệm ( (víví dụdụ: : NhấnNhấn phímphím BộBộ đệmđệm CPUCPU xửxử lýlý).). XửXử lýlý cáccác lệnhlệnh trongtrong máymáy tínhtính ( (ứngứng dụngdụng trongtrong HĐHHĐH, ,
trìnhtrình biênbiên dịchdịch), ), hànghàng đợiđợi cáccác tiếntiến trìnhtrình chờchờ đượcđược xửxử lýlý, , ……..
Ứng dụng STACK để khử đệ Ứng dụng STACK để khử đệ quy cho bài toán tháp Hà Nộiquy cho bài toán tháp Hà Nội
86
Bài toán Tháp Hà nộiBài toán Tháp Hà nội
Luật:Luật: Di chuyển mỗi lần một đĩaDi chuyển mỗi lần một đĩa Không được đặt đĩa lớn lên trên đĩa nhỏKhông được đặt đĩa lớn lên trên đĩa nhỏ
87
Bài toán Tháp Hà nội – Thiết kế Bài toán Tháp Hà nội – Thiết kế hàmhàm
Hàm đệ qui:Hàm đệ qui: Chuyển (count-1) đĩa trên đỉnh của cột start sang cột Chuyển (count-1) đĩa trên đỉnh của cột start sang cột
temptemp Chuyển 1 đĩa (cuối cùng) của cột start sang cột finishChuyển 1 đĩa (cuối cùng) của cột start sang cột finish Chuyển count-1 đĩa từ cột temp sang cột finishChuyển count-1 đĩa từ cột temp sang cột finish
magic
88
Bài toán Tháp Hà nội – Mã C++Bài toán Tháp Hà nội – Mã C++
void move(int n, char start, char finish, char temp) {
if (n > 0) { move(n − 1, start, temp, finish); cout << "Move disk " << n << " from " ;
cout<< start << " to " << finish << "." << endl;
move(n − 1, temp, finish, start); }}