890 likes | 1.1k Views
Danh sách liên kết ( List ). Danh saùch keà :
E N D
Danhsáchliênkết (List) • Danh saùch keà : • 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 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 vuøng tin. Maûng hay chuoãi laø daïng cuûa danh saùch keà. • Ñòa chæ cuûa moãi node trong danh saùch ñöôïc 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 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á 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 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 hay xoùa phaàn töû treân danh saùch,
Danhsáchliênkết (List) • Danh saùch lieân keát : • 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 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 node tröôùc noù. • 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 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æ 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 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. 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öø ñaàu danh saùch.
Danhsáchliênkết (List) • Cónhiềukiểutổchứcliênkếtgiữacácphầntửtrongdanhsáchnhư : • Danhsáchliênkếtđơn • Danhsáchliênkếtkép • Danhsáchliênkếtvòng • …
A B X Z Y D A B C Danhsáchliênkết (List) • Danhsáchliênkếtđơn:mỗiphầntửliênkếtvớiphầntửđứngsaunótrongdanhsách: • Danhsáchliênkếtkép:mỗiphầntửliênkếtvớicácphầntửđứngtrướcvàsaunótrongdanhsách:
A B C A B X Z Y D Danhsáchliênkết (List) • Danhsáchliênkếtvòng :phầntửcuốidanhsáchliênkếtvớiphầntửđầudanhsách:
Sắpxếpdanhsách Cáchtiếpcận: • Phương án 1: Hoán vị nội dung các phần tử trong danh sách (thao tác trên vùng data). • Phương án 2 : Thay đổi các mối liên kết (thao tác trên vùng link)
SắpxếpdanhsáchHoánvịnộidungcácphầntửtrongdanhsáchSắpxếpdanhsáchHoánvịnộidungcácphầntửtrongdanhsách • Càiđặtlạitrêndanh sách liên kếtmộttrongnhữngthuậttoánsắpxếpđãbiếttrênmảng • Điểmkhácbiệtduynhấtlàcáchthứctruyxuấtđếncácphầntửtrêndanh sách liên kếtthôngqualiênkếtthayvìchỉsốnhưtrênmảng. • Dothựchiệnhoánvịnộidungcủacácphầntửnênđòihỏisửdụngthêmvùngnhớtrunggian chỉthíchhợpvớicácxâucócácphầntửcóthànhphầndatakíchthướcnhỏ. • Khikíchthướccủatrườngdatalớn, việchoánvịgiátrịcủahaiphântửsẽchiếmchiphíđángkể.
Sắp xếp bằng phương pháp đổi chổ trực tiếp ( Interchange Sort ) voidSLL_InterChangeSort ( List &l ) { for ( Node* p=l.first ; p!=l.last ; p=p->link ) for ( Node* q=p->link ; q!=NULL ; q=q->link ) if ( p->data > q->data ) Swap( p->data , q->data ); }
Sắp xếp đổi chổ trực tiếp ( Interchange Sort ) l.last q l.first 12 2 8 1 5 p
Sắp xếp đổi chổ trực tiếp ( Interchange Sort ) l.last q l.first 1 12 8 2 5 p
Sắp xếp đổi chổ trực tiếp ( Interchange Sort ) l.last q l.first 1 2 12 8 5 p
Sắp xếp đổi chổ trực tiếp ( Interchange Sort ) l.last q l.first 1 2 5 12 8 p
Sắp xếp đổi chổ trực tiếp ( Interchange Sort ) Dừng l.last q l.first 1 2 5 8 12 p
Sắp xếp bằng phương pháp chọn trực tiếp ( Selection sort ) voidListSelectionSort (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); } }
Sắp xếp bằng phương pháp chọn trực tiếp ( Selection sort ) l.last min l.first 12 2 8 1 5 p
Sắp xếp bằng phương pháp chọn trực tiếp( Selection sort ) l.last min l.first 1 2 8 12 5 p
Sắp xếp bằng phương pháp chọn trực tiếp ( Selection sort ) l.last min l.first 1 2 8 12 5 p
Sắp xếp bằng phương pháp chọn trực tiếp( Selection sort ) l.last min l.first 1 2 5 12 8 p
Sắp xếp bằng phương pháp chọn trực tiếp( Selection sort ) Dừng l.last min l.first 1 2 5 8 12 p
Sắp xếp bằng phương pháp nổi bọt ( Bubblesort ) void SLL_BubleSort ( List l ) { Node* t = l.last ; for ( Node* p = l.first ; p != NULL ; p = p->link) { Node* t1; for ( Node* q=l.first ; p!=t ; q=q->link ) { if( q->data > q->link->data ) Swap( q->data , q->link->data ); t1 = q ; } t = t1; } }
Sắp xếp bằng phương pháp nổi bọt ( Bubble sort ) l.last q->link l.first 12 2 8 1 5 q
Sắp xếp bằng phương pháp nổi bọt ( Bubble sort ) l.last q->link l.first 2 8 1 5 12 q
Sắp xếp bằng phương pháp nổi bọt ( Bubble sort ) l.last q->link l.first 2 1 5 8 12 q
Sắp xếp bằng phương pháp nổi bọt ( Bubble sort ) l.last q->link l.first 1 2 5 8 12 q
Sắp xếp bằng phương pháp nổi bọt ( Bubble sort ) Dừng l.last l.first 1 2 5 8 12
SắpxếpThayđổicácmốiliênkết • 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 muốn chỉ thao tác trên các móc nối (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 • 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…) • 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. 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ả nào đó.
p 8 Phương pháp lấy Node ra khỏi danh sách giữ nguyên địa chỉ của Node q 12 2 5 1 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
Quick Sort : Thuật toán //input: xâu (first, last) //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ử Dừng; //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 khỏi L. • Bước 3: Tách xâu L ra làm 2 xâu L1 (gồm các phần tử nhỏ hơn hay bằng X) và L2 (gồm các phần tử lớn hơn X). • Bước 4: Sắp xếp Quick Sort (L1). • Bước 5: Sắp xếp Quick Sort (L2). • Bước 6: Nối L1, X, và L2 lại theo trình tự ta có xâu L đã được sắp xếp.
6 4 5 1 8 2 Sắpxếpquicksort first
6 4 5 1 8 2 Quicksort : phânhoạch first X Chọnphầntửđầuxâulàmngưỡng
Quicksort : phânhoạch first1 1 first 8 4 X 2 5 6 first2 Táchxâuhiệnhànhthành 2 xâu
Quicksort : phânhoạch first1 1 first 8 4 X 2 5 6 first2 Táchxâuhiệnhànhthành 2 xâu
Quicksort : phânhoạch first1 1 first 8 4 X 2 5 6 first2 Táchxâuhiệnhànhthành 2 xâu
Quicksort : phânhoạch first1 1 first 8 4 X 2 5 6 first2 Táchxâuhiệnhànhthành 2 xâu
Quicksort first1 1 first 8 4 X 2 5 6 first2 Sắpxếpcácxâu l1, l2
Quicksort first1 Đưakếtquảvào first Nối l1, X, l2 1 first 8 4 X 2 5 6 first2
Nối 2 danh sách voidSListAppend(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); }
voidSListQSort(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); elseAddFirst(l2, p); } SListQSort(l1); SListQSort(l2); SListAppend(l, l1); AddFirst(l, X); SListAppend(l, l2); }
Quicksort : nhậnxét • Nhậnxét: • Quicksorttrênxâuđơnđơngiảnhơnphiênbảncủanótrênmảngmộtchiều • Khidùngquicksortsắpxếpmộtxâuđơn, chỉcómộtchọnlựaphầntửcầmcanhduynhấthợplýlàphầntửđầuxâu. Chọnbấtkỳphầntửnàokháccũnglàmtăngchiphímộtcáchkhôngcầnthiếtdocấutrúctựnhiêncủaxâu.
Stack • Stacklàmộtvậtchứa (container) cácđốitượnglàmviệctheocơchếLIFO (LastInFirstOut) Việcthêmmộtđốitượngvàostackhoặclấymộtđốitượngrakhỏistackđượcthựchiệntheocơchế“Vào sau ratrước”. • Cácđốitượngcóthểđượcthêmvàostackbấtkỳlúcnàonhưngchỉcóđốitượngthêmvàosaucùngmớiđượcphéplấyrakhỏistack. • “Push”: Thaotácthêm 1 đốitượngvàostack • “Pop”: Thaotáclấy 1 đốitượngrakhỏistack. • Stackcónhiềuứngdụng: khửđệqui, tổchứclưuvếtcácquátrìnhtìmkiếmtheochiềusâuvàquaylui, vétcạn, ứngdụngtrongcácbàitoántínhtoánbiểuthức, …
Giới thiệu • LIFO: Last In First Out • Thao tác Pop, Push chỉ diễn ra ở 1 đầu Pop Push Stack 3 2 5
Hiện thực stack(Implementation of a Stack ) Mảng 1 chiều Danh sách LK Cấp phát động! Kích thước stack khi quá thiếu, lúc quá thừa Push/Pop khá dễ dàng Push / Pop hơi phức tạp
Stack ( Ngăn xếp ) • StacklàmộtCTDLtrừutượngtuyếntínhhỗtrợ 2 thaotácchính: • Push(o): Thêmđốitượngovàođầustack • Pop(): Lấyđốitượngởđầustackrakhỏistackvàtrảvềgiátrịcủanó. Nếustackrỗngthìlỗisẽxảyra. • Stackcũnghỗtrợmộtsốthaotáckhác: • isEmpty(): Kiểmtraxemstackcórỗngkhông. • Top(): Trảvềgiátrịcủaphầntửnằmởđầustackmàkhônghủynókhỏistack. Nếustackrỗngthìlỗisẽxảyra.
BiểudiễnStackdùngmảng (Array Implementation of a Stack) • Cóthểtạomộtstackbằngcáchkhaibáomộtmảng 1 chiềuvớikíchthướctốiđalàN (vídụ: N =1000). • StackcóthểchứatốiđaNphầntửđánhsốtừ 0 đếnN-1. • Phầntửnằmởđầustacksẽcóchỉsốtop (lúcđótrongstackđangchứatop +1 phầntử) • Đểkhaibáomộtstack, tacầnmộtmảng 1 chiềuS, biếnnguyêntchobiếtchỉsốcủađầustackvàhằngsốNchobiếtkíchthướctốiđacủastack. DataS [N]; inttop;
BiểudiễnStackdùngmảng • Lệnhtop = 0 sẽtạoramộtstackSrỗng. • Giátrịcủatop+1sẽchobiếtsốphầntửhiệnhànhcótrongstack. • Khicàiđặtbằngmảng 1 chiều, stackcókíchthướctốiđanêncầnxâydựngthêmmộtthaotácphụchostack: • Full(): Kiểmtraxemstackcóđầychưa. • Khistackđầy, việcgọiđếnhàmpush() sẽphátsinhralỗi.
Khai báo stack typedef struct node { int data; }; typedef struct stack { int top; node list[N]; };
Biểu diễn Stack dùng mảng • Khởi tạo Stack: voidInit(stack &s) { s.top=0; }