[Huong Dan Tieng Viet] Cac Van de Voi DSLK

Embed Size (px)

Citation preview

  • 8/6/2019 [Huong Dan Tieng Viet] Cac Van de Voi DSLK

    1/30

    More information: www.itspiritclub.net Translater: huahongquan2007

    1

    i vi vi vn chng ti a ra nhiu gii php, nh l vng lp v quy, dummy node v tham chiu ccb. Nhng vn c trnh by theo th t t d ti kh: Count, GetNth, DeleteList, Pop, InsertNth, SortedInsert,InsertSort, Append, FrontBackSplit, RemoveDuplicates, MoveNode, AlternatingSplit, ShuffleMerge, SortedMerge,SortedIntersect, Reverse, and RecursiveReverse.

    Ni dung:

    Phn 1 n li v danh sch lin kt

    Phn 2 18 vn theo th t t d ti kh

    Phn 3 Gii php ti tt c vn

  • 8/6/2019 [Huong Dan Tieng Viet] Cac Van de Voi DSLK

    2/30

    More information: www.itspiritclub.net Translater: huahongquan2007

    2

    Phn 1 Xem li cc k thut c bn vDSLK

    Phn ny s n li nhanh v cc khi nim c dng trong danh sch lin kt. bit chi tit hn, hy xem tiliu C bn v danh sch lin kt ( http://itspiritclub.net ).

    Cc nguyn tc c bn ca danh sch lin kt

    Tt c cc m ngun v danh sch lin kt trong ti liu ny dng cu trc danh sch lin kt n thun ty: chdng mt con trhead tr ti node u tin ca danh sch. Mi node cha mt con tr.next tr ti node tip theo.Con tr .next cui cng l NULL. Danh sch rng th biu din bng mt con tr head NULL. Tt c cc node th ccp pht trn heap.

    struct node {

    int data;

    struct node* next;

    };

    Cc hm tin ch c bn

    vi ch, chng ta tha nhn s c mt ca cc hm tin ch sau:

    int Length(struct node* head);Tr v slng node ca danh sch

    struct node* BuildOneTwoThree();Cp pht v tr v mt danh sch {1, 2, 3}.

    void Push(struct node** headRef, int newData);a mt s int v mt tham chiu ti con tr head, thm mt node u ca danh sch vi 3 bc cbn.

    Cch dng cc hm tin ch c bn:

    on m ngun di y m t cch s dng hm tin ch c bn.

    void BasicsCaller() {

    struct node* head;

    int len;

    head = BuildOneTwoThree(); // Start with {1, 2, 3}Push(&head, 13); // Push 13 on the front, yielding {13, 1, 2, 3}// (The '&' is because head is passed

    // as a reference pointer.)Push(&(head->next), 42); // Push 42 into the second position

    // yielding {13, 42, 1, 2, 3}// Demonstrates a use of '&' on// the .next field of a node.// (See technique #2 below.)len = Length(head); // Computes that the length is 5.

    }

  • 8/6/2019 [Huong Dan Tieng Viet] Cac Van de Voi DSLK

    3/30

    More information: www.itspiritclub.net Translater: huahongquan2007

    3

    # Cc phn cn li ca phn 1 ging hon ton ti liu trc

  • 8/6/2019 [Huong Dan Tieng Viet] Cac Van de Voi DSLK

    4/30

    More information: www.itspiritclub.net Translater: huahongquan2007

    4

    Phn 2 Cc vn vi DSLK

    y l 18 vn v danh sch lin kt c sp xp theo th tkh tng dn. Vi vn u th kh l cbn, nhng vn cui th nng cao hn. Mi vn bt u vi mt nh ngha c bn viu g cn phi hon thnh.Nhiu vn cng bao hm cc gi hoc hnh v bn nm bt c. Gii php cho tt c cc vn th c trnhby trong phn tip theo.

    cc vn ny gip ch c cho bn, bn cn phi c gng suy ngh v chng. D bn c gii c vn hay khng, bn s vn c suy ngh vng vn v gii php a ra s lm r vn hn.

    Nhng lp trnh vin tt c th hnh dung ra cu trc d liu thy m ngun v b nhstng tc nh thno. Hy dng nhng vn pht trin k nng tng tng ca bn. Hy v nhng hnh m phng qu trnh hot ngca m ngun. Dng cc hnh v chun b cho vic hnh dung ra gii php.

    Vit mt hm Count() m s ln xut hin ca mt bin int c a ra trong sch.

    Vit mt hm GetNth() nhn mt danh sch lin kt v mt ch s index nguyn v tr v gitr d liu lu trong node v tr ch s. GetNth() dng quy c nh strong C : node u c index 0,th hai l index 1.V d vi danh sch {42, 13, 666} GetNth() vi index 1 s tr v 13. Index s cgi tr trong khong range [0..length-1]. Nu n khng phi vy, GetNth() s tht bi.

    Vc bn, GetNth() th tng tnh array[i] . Tuy nhin, GetNth() th x l chm hn c php [ ] ca mng.Thun li ca danh sch lin kt l n qun l b nhlinh ng hn chng ta c th Push() bt clc no thm mtphn t khi cn.

    void CountTest() {

    List myList = BuildOneTwoThree(); // build {1, 2, 3}

    int count = Count(myList, 2); // returns 1 since there's 1 '2' in the list

    }

    /*Given a list and an int, return the number of times that int occursin the list.

    */

    int Count(struct node* head, int searchFor) {

    // Your code

    void GetNthTest() {

    struct node* myList = BuildOneTwoThree(); // build {1, 2, 3}int lastNode = GetNth(myList, 2); // returns the value 3

    }

  • 8/6/2019 [Huong Dan Tieng Viet] Cac Van de Voi DSLK

    5/30

    More information: www.itspiritclub.net Translater: huahongquan2007

    5

    Vit mt hm DeleteList() nhn mt danh sch v gii phng tt c b nhca n v t con tr head vNULL.

    Hnh vm phng b nhDeleteList()

    Hnh vsau y s m phng trng thi ca b nhsau khi DeleteList() hot ng trong v d trn. Con trcghi s hin ln trong mu xm v b nhc gii phng c mt du X trn n. Vc bn DeleteList() cn gi hmfree() mi ln cho mi node v t con tr head v NULL.

    DeleteList() cn s dng i s tham chiu ging nh Push() n c ththay i b nhca hm gi. Hm cng cnphi cn thn khng truy cp vo trng .next ca mt node sau khi node b gii phng.

    void DeleteList(struct node** headRef) {

    // Your code

    void DeleteListTest() {

    struct node* myList = BuildOneTwoThree();// build {1, 2, 3}DeleteList(&myList); // deletes the three nodes and sets myList to NULL

    }

  • 8/6/2019 [Huong Dan Tieng Viet] Cac Van de Voi DSLK

    6/30

    More information: www.itspiritclub.net Translater: huahongquan2007

    6

    Vit mt hm Pop() m n ngc li vi Push(). Pop() nhn mt danh sch khng rng v xa node head v tr vd liu node head. Nu bn tng s dng Push() v Pop(), th danh sch ca bn s ging nh mt STACK. Tuy nhin,chng ta cung cp nhiu hm h trnh GetNth() nn danh sch chng ta s ging mt danh sch lin kt n hn ch lmt stack. Pop() s tht bi nu nh khng c node Pop. Di y l vi v d:

    Hnh vm phng b nhPop()

    Pop()

    /*

    The opposite of Push(). Takes a non-empty list

    and removes the front node, and returns the data

    which was in that node.*/

    int Pop(struct node** headRef) {

    // your code...

    void PopTest() {

    struct node* head = BuildOneTwoThree(); // build {1, 2, 3}int a = Pop(&head); // deletes "1" node and returns 1int b = Pop(&head); // deletes "2" node and returns 2int c = Pop(&head); // deletes "3" node and returns 3int len = Length(head); // the list is now empty, so len == 0

    }

  • 8/6/2019 [Huong Dan Tieng Viet] Cac Van de Voi DSLK

    7/30

    More information: www.itspiritclub.net Translater: huahongquan2007

    7

    Mt vn kh hn l vit mt hm InsertNth() m n chn thm mt node mi vo mt v tr th index trongdanh sch. Push() th tng tnhng ch c th chn mt node u trong danh sch (index 0). Index phi trongkhong [0 length], v node mi sc chn v tr index.

    InsertNth() th kh phc tp c l bn s cn v hnh m phng suy ngh vhng gii v kim tra chnhxc.

    Vit mt hm SortedInsert() m nhn ra mt danh sch c sp tng v mt node n l, sau chn nodevo ng vtr c sp xp trong danh sch. Trong khi hm Push() cp pht mt node mi v thm vo danh sch,SortedInsert() nhn mt node c sn v chthay i con tr n chn vo trong danh sch. C nhiu gii php cho vn ny.

    Vit mt hm InsertSort() m nhn mt danh sch, v sp xp cc node ca n chng c sp xp theo th ttng dn. N s dng SortedInsert().

    void InsertNthTest() {struct node* head = NULL; // start with the empty listInsertNth(&head, 0, 13); // build {13)InsertNth(&head, 1, 42); // build {13, 42}InsertNth(&head, 1, 5); // build {13, 5, 42}

    DeleteList(&head); // clean up after ourselves}

    void SortedInsert(struct node** headRef, struct node* newNode) {// Your code...

    /*A more general version of Push().Given a list, an index 'n' in the range 0..length,

    and a data element, add a new node to the list sothat it has the given index.*/

    void InsertNth(struct node** headRef, int index, int data) {

    // your code...

  • 8/6/2019 [Huong Dan Tieng Viet] Cac Van de Voi DSLK

    8/30

    More information: www.itspiritclub.net Translater: huahongquan2007

    8

    Vit mt hm Append() m nhn hai danh sch , a v b , ni b vo cui ca a ,v khi t b thnhNULL. Di y l hnh v m phng Append(a, b) vi trng thi ban u l mu xm v trng thi cui cng l muen. cui ca ln gi, danh sch s l {1, 2, 3, 4} v b th rng

    R rng l c hai con tru c truyn vo trong Append(a, b) cn phi l i s tham chiu v chng u phibthay i. i s th hai b th lun phi c gn v NULL. Vy khi no th a thay i ? Trng hp xy ra khidanh sch a lc bt u l mt danh sch rng. Trong trng hp , con tr head ca a cn phi chuyn t NULLsang tr ti danh sch b.

    // Given a list, change it to be in sorted order (using SortedInsert()).

    void InsertSort(struct node** headRef) {

    // Your code

    // Append 'b' onto the end of 'a', and then set 'b' to NULL.

    void Append(struct node** aRef, struct node** bRef) {

    // Your code...

  • 8/6/2019 [Huong Dan Tieng Viet] Cac Van de Voi DSLK

    9/30

    More information: www.itspiritclub.net Translater: huahongquan2007

    9

    Hm FrontBackSplit() s nhn mt hm danh sch v sau ct danh sch thnh hai danh sch nh - mt danhsch trc v mt danh sch sau. Nu slng cc phn t th l, phn t tha si vo danh sch trc. VyFrontBackSplit() i vi danh sch {2, 3, 5, 7, 11} s chia thnh hai danh sch nh{2, 3, 5} v {7, 11}. lm ng ttccc trng hp th kh l kh. Bn cn phi kim tra gii php ca bn i vi cc trng hp (length = 2, length = 3,

    length=4) chc chn rng danh sch c ct ng nh iu kin bi. Nu n hot ng ng cho length = 4, n shot ng cho length = 1000. Bn cng cn phi x l trng hp c bit l length < 2.

    Gi : Chin lc d nht l tnh ton chiu di ca danh sch, sau dng mt vng lp nhy qua cc node tmnode cui cng ca na danh sch trc v ct danh sch ng im . C mt k thut l s dng hai con trltqua danh sch. Mt con tr chm tin ti mt node mi ln, trong khi con tr nhanh th ti hai node mi ln. Khi mcon trnhanh n cui danh sch, con tr chm sgia qung ng. i vi cc chin lc khc, iu cn quan tml chia danh sch ng v tr.

    Vit mt hm RemoveDuplicates() nhn mt danh sch, sp xp chng theo th ttng dn v xa nhng nodetrng nhau trong danh sch. cho l tng, danh sch cn c nghin cu ton b mt ln.

    y l mt bin th ca Push(). Thay v to ra mt node v push n vo trong danh sch co sn, MoveNode() snhn hai danh sch, bi node trc (front node) ca danh sch thhaiv push n vo u danh sch th nht. HmMoveNode() trthnh mt hm tin ch rt c li cho nhiu vn sau. Chai Push() v MoveNode() c thit kquanh c trng l cc hm trong danh sch thng hot ng ch yu u danh sch. Di y l vi v d:

    /*Split the nodes of the given list into front and back halves,and return the two lists using the reference parameters.

    If the length is odd, the extra node should go in the front list.*/

    void FrontBackSplit(struct node* source,

    struct node** frontRef, struct node** backRef) {

    // Your code...

    /*Remove duplicates from a sorted list.*/

    void RemoveDuplicates(struct node* head) {

    // Your code...

  • 8/6/2019 [Huong Dan Tieng Viet] Cac Van de Voi DSLK

    10/30

    More information: www.itspiritclub.net Translater: huahongquan2007

    10

    Vit mt hm AlternatingSplit() m nhn mt danh sch v chia cc node ca n to thnh hai danh sch nh

    hn. Danh sch nh phi c lm t cc phn t lun phin nhau trong danh sch gc. Nu danh sch l {a , b, a, b, a}th danh sch ph l {a, a, a} v danh sch cn li l { b, b}. Bn s cn dng hm MoveNode(). Cc phn t trong danhsch mi c thth t bt k.

    Nhn hai danh sch, trn cc node vi nhau to thnh mt danh sch, nhn cc node lun phin nhau gia haidanh sch. Vy ShuffleMerge() vi {1, 2, 3} v {7 , 13, 1} s to ra danh sch {1, 7, 2, 13, 3, 1}. Nu mt trong hai danhsch ht node, hm s ly ht tt c cc node cn li ca danh sch kia. Gii php th ph thuc trn khnng di chuyncc node ti cui ca mt danh sch nh bn phn 1. Bn c th s dng hm MoveNode(). Nu s dng hm

    FrontBackSplit(), bn c th gi lp qu trnh xo bi.

    void MoveNodeTest() {

    struct node* a = BuildOneTwoThree(); // the list {1, 2, 3}

    struct node* b = BuildOneTwoThree();

    MoveNode(&a, &b);

    // a == {1, 1, 2, 3}

    // b == {2, 3}

    }

    /*Take the node from the front of the source, and move it to

    the front of the dest.It is an error to call this with the source list empty.*/

    void MoveNode(struct node** destRef, struct node** sourceRef) {// Your code

    /*Given the source list, split its nodes into two shorter lists.

    If we number the elements 0, 1, 2, ... then all the even elementsshould go in the first list, and all the odd elements in the second.The elements in the new lists may be in any order.*/

    void AlternatingSplit(struct node* source,

    struct node** aRef, struct node** bRef) {

    // Your code

    /*

    Merge the nodes of the two lists into a single list taking a node

    alternately from each list, and return the new list.

    */

    struct node* ShuffleMerge(struct node* a, struct node* b) {// Your code

  • 8/6/2019 [Huong Dan Tieng Viet] Cac Van de Voi DSLK

    11/30

    More information: www.itspiritclub.net Translater: huahongquan2007

    11

    Vit mt hm SortedMerge() nhn hai danh sch, mi ci th c sp xp tng dn, v trn hai ci li vinhau thnh mt mng tng dn. C nhiu trng s xy ra: c th a hoc b c th trng, trong qu trnh x l c tha hoc b ht trc v cui cng th c vn t vic bt u t mt danh sch rng v xy dng n trong khi i quaa v b.

    (Vn ny yu cu quy) Nhn mt FrontBackSplit() v SortedMerge(), n th kh d vit mt hmMergeSort() quy: ct danh sch lm hai phn nhhn, sp xp theo quy hai danh sch v cui cng ni cc danhsch c sp xp li vi nhau thnh mt danh sch n. Trtru thay, vn ny th dhn l FrontBackSplit haySortedMerge.

    Nhn hai danh sch sp xp tng, to v tr v mt danh sch mi i din cho ch giao nhau ca hai danhsch. Danh sch mi nn c b nhca chnh n cc danh sch gc th khng nn bthay i. Ni cch khc, nn sdng Push() xy dng danh sch ch khng phi MoveNode().

    /*Takes two lists sorted in increasing order, andsplices their nodes together to make one bigsorted list which is returned.*/

    struct node* SortedMerge(struct node* a, struct node* b) {// your code...

    /*

    Compute a new sorted list that represents the intersectionof the two given sorted lists.*/

    struct node* SortedIntersect(struct node* a, struct node* b) {

    // Your code

    void MergeSort(struct node* headRef) {

    // Your code...

  • 8/6/2019 [Huong Dan Tieng Viet] Cac Van de Voi DSLK

    12/30

    More information: www.itspiritclub.net Translater: huahongquan2007

    12

    Vit mt hm Reverse() lp o ngc mt danh sch bng cch sa li tt ctrng .next v con tr head.Gii php lp th kh l phc tp. N th khng qu kh t cui ti liu ny, nhng n cn thit x l vn th18.

    "Push" Reverse Hint

    Qu trnh lp qua danh sch chnh. Di chuyn mi node ti u trc ca danh sch kt qu khi bn thc hin.Ging nh l Push() cho mi node, ngoi tr bn thay i con tr trong cc node c sn thay v cp pht li n. Bn c thdng MoveNode() thc hin hu ht cng vic hoc l thay i con tr bng tay.

    "3 Pointers" Hint

    K thut ny khng tt nh k thut Push. Thay v chy mt con tr current xung danh sch, chy ba con tr(front, middle, back) xung danh sch theo th t : front l mt node, middle l node sau v back l node sau middle.Khi code chy 3 con tr xung r rng, kim tra trong mt hnh minh ha, thm code o trng .next ca nodemiddle trong qu trnh lp. Thm code x l danh sch rng v thay i con tr head.

    void ReverseTest() {struct node* head;

    head = BuildOneTwoThree();

    Reverse(&head);

    // head now points to the list {3, 2, 1}

    DeleteList(&head); // clean up after ourselves}

    /*Reverse the given linked list by changing its .next pointers andits head pointer. Takes a pointer (reference) to the head pointer.*/

    void Reverse(struct node** headRef) {

    // your code...

  • 8/6/2019 [Huong Dan Tieng Viet] Cac Van de Voi DSLK

    13/30

    More information: www.itspiritclub.net Translater: huahongquan2007

    13

    (Vn ny th kh v ch nn lm nu bn quen vi quy) C mt gii php quy hiu qu v ngn gn cho vn ny.

    /*

    Recursively reverses the given linked list by changing its .nextpointers and its head pointer in one pass of the list.*/

    void RecursiveReverse(struct node** headRef) {

    // your code...

  • 8/6/2019 [Huong Dan Tieng Viet] Cac Van de Voi DSLK

    14/30

    More information: www.itspiritclub.net Translater: huahongquan2007

    14

    Phn 3 Gii php i vi cc vn

    Mt vng lp thng xung danh sch ging nh Length().

    C th dng for thay cho while

    Kt hp vng lp danh sch c bn vi vn m tm ra node ng. C nhng li th thng dng trongloi code ny. Kim tra n k trong nhng trng hp n gin. Nu code hot ng ng cho n = 0, n = 1 v n =2 th nsng cho n = 1000

    int Count(struct node* head, int searchFor) {

    struct node* current = head;

    int count = 0;

    while (current != NULL) {

    if (current->data == searchFor) count++;

    current = current->next;

    }

    return count;}

    int Count2(struct node* head, int searchFor) {

    struct node* current;

    int count = 0;

    for (current = head; current != NULL; current = current->next) {

    if (current->data == searchFor) count++;

    }

    return count;

    }

    int GetNth(struct node* head, int index) {

    struct node* current = head;int count = 0; // the index of the node we're currently looking at

    while (current != NULL) {

    if (count == index) return(current->data);

    count++;

    current = current->next;

    }

    assert(0); // if we get to this line, the caller was asking

    // for a non-existent element so we assert fail.}

  • 8/6/2019 [Huong Dan Tieng Viet] Cac Van de Voi DSLK

    15/30

    More information: www.itspiritclub.net Translater: huahongquan2007

    15

    Xa ton b danh sch v t con tr head v NULL. C mt s phc tp trong vng lp do chng ta cn phitch con tr.next trc khi chng ta xa node, v sau khi xa, n s khng kh dng na.

    Tch d liu khi node u, xa node, tin con trhead tr ti node tip theo. Dng i s tham chiu v nthay i con tr head.

    on m ny x l vic chn vo u nh l mt trng hp c bit. Mc d n hot ng bng cch chycon tr current ti node trc node cn thm vo. Dng mt vng lp kim tra con tr chnh xc.

    void DeleteList(struct node** headRef) {

    struct node* current = *headRef;// deref headRef to get the real head

    struct node* next;

    while (current != NULL) {

    next = current->next; // note the next pointerfree(current); // delete the nodecurrent = next; // advance to the next node

    }

    *headRef = NULL; // Again, deref headRef to affect the real head back

    // in the caller.}

    int Pop(struct node** headRef) {

    struct node* head;

    int result;

    head = *headRef;

    assert(head != NULL);

    result = head->data; // pull out the data before the node is deleted

    *headRef = head->next; // unlink the head node for the caller// Note the * -- uses a reference-pointer// just like Push() and DeleteList().free(head); // free the head nodereturn(result); // don't forget to return the data from the link

    }

  • 8/6/2019 [Huong Dan Tieng Viet] Cac Van de Voi DSLK

    16/30

    More information: www.itspiritclub.net Translater: huahongquan2007

    16

    Chin lc c bn l duyt xung danh sch tm ni chn node mi vo. C th l cui ca mt danh schhoc l mt im trc node m ln hn node mi. C ba gii php cho ba cch khc nhau:

    void InsertNth(struct node** headRef, int index, int data) {

    // position 0 is a special case...

    if (index == 0) Push(headRef, data);

    else {

    struct node* current = *headRef;

    int i;

    for (i=0; inext;

    }assert(current != NULL); // tricky: you have to check one last timePush(&(current->next), data); // Tricky use of Push() --// The pointer being pushed on is not// in the stack. But actually this works// fine -- Push() works for any node pointer.

    }}

    // Uses special case code for the head end

    void SortedInsert(struct node** headRef, struct node* newNode) {

    // Special case for the head end

    if (*headRef == NULL || (*headRef)->data >= newNode->data) {

    newNode->next = *headRef;

    *headRef = newNode;

    }

    else {

    // Locate the node before the point of insertionstruct node* current = *headRef;

    while (current->next!=NULL && current->next->datadata) {

    current = current->next;

    }

    newNode->next = current->next;

    current->next = newNode;

    }

    }

  • 8/6/2019 [Huong Dan Tieng Viet] Cac Van de Voi DSLK

    17/30

    More information: www.itspiritclub.net Translater: huahongquan2007

    17

    Bt u vi mt danh sch kt qu rng. Duyt xung danh sch ngun v SortedInsert() mi nodes ca nvo danh sch kt qu. Cn thn ch ti trng .next trong mi node trc khi di chuyn n vo danh sch kt qu.

    // Dummy node strategy for the head end

    void SortedInsert2(struct node** headRef, struct node* newNode) {

    struct node dummy;

    struct node* current = &dummy;

    dummy.next = *headRef;

    while (current->next!=NULL && current->next->datadata) {

    current = current->next;

    }

    newNode->next = current->next;

    current->next = newNode;*headRef = dummy.next;

    }

    // Local references strategy for the head end

    void SortedInsert3(struct node** headRef, struct node* newNode) {

    struct node** currentRef = headRef;

    while (*currentRef!=NULL && (*currentRef)->datadata) {

    currentRef = &((*currentRef)->next);

    }

    newNode->next = *currentRef; // Bug: this line used to have// an incorrect (*currRef)->next

    *currentRef = newNode;}

    // Given a list, change it to be in sorted order (using SortedInsert()).void InsertSort(struct node** headRef) {

    struct node* result = NULL; // build the answer herestruct node* current = *headRef; // iterate over the original list

    struct node* next;

    while (current!=NULL) {

    next = current->next; // tricky - note the next pointer before we change i

    SortedInsert(&result, current);

    current = next;

    }

    *headRef = result;

    }

  • 8/6/2019 [Huong Dan Tieng Viet] Cac Van de Voi DSLK

    18/30

    More information: www.itspiritclub.net Translater: huahongquan2007

    18

    Trng hp m danh sch a l rng l mt trng hp c xl u tin trong trng hp con tr heada cn phi thay i trc tip. Mc khc, chng ta duyt xung danh sch a cho ti khi chng ta tm thy node cui viphp kim tra (current->next != NULL), v nh danh sch b y. Cui cng, con tr head b th c gn v NULLon code chng minh vic dng rng ri ca i s tham chiu ca con tr v nhng vn thng thng m cn thit

    xc nh v tr ca node cui trong danh sch.

    Append() Test and Drawing

    Hm AppendTest() sau gi hm Append() ni hai danh sch. B nhsnh th no sau khi hm Append()thot?

    Hy ch cch m i s tham chiu trong Append() tr v con tr head trong AppendTest()

    void Append(struct node** aRef, struct node** bRef) {

    struct node* current;

    if (*aRef == NULL) { // Special case if a is empty*aRef = *bRef;

    }

    else { // Otherwise, find the end of a, and append b there

    current = *aRef;

    while (current->next != NULL) { // find the last node

    current = current->next;

    }

    current->next = *bRef; // hang the b list off the last node

    }*bRef=NULL; // NULL the original b, since it has been appended above

    }

    void AppendTest() {

    struct node* a;struct node* b;

    // set a to {1, 2}

    // set b to {3, 4}

    Append(&a, &b);}

  • 8/6/2019 [Huong Dan Tieng Viet] Cac Van de Voi DSLK

    19/30

    More information: www.itspiritclub.net Translater: huahongquan2007

    19

    C hai gii php cho trng hp ny

    // Uses the "count the nodes" strategyvoid FrontBackSplit(struct node* source,

    struct node** frontRef, struct node** backRef) {

    int len = Length(source);

    int i;

    struct node* current = source;

    if (len < 2) {

    *frontRef = source;

    *backRef = NULL;

    }

    else {

    int hopCount = (len-1)/2; //(figured these with a few drawings)

    for (i = 0; inext;

    }

    // Now cut at current

    *frontRef = source;*backRef = current->next;

    current->next = NULL;

    }}

    // Uses the fast/slow pointer strategy

    void FrontBackSplit2(struct node* source,

    struct node** frontRef, struct node** backRef) {

    struct node* fast;

    struct node* slow;

    if (source==NULL || source->next==NULL) { // length < 2 cases*frontRef = source;

    *backRef = NULL;

    }

    else {

    slow = source;

    fast = source->next;

    // Advance 'fast' two nodes, and advance 'slow' one node

    while (fast != NULL) {

    fast = fast->next;

    if (fast != NULL) {

    slow = slow->next;

    fast = fast->next;

    }

    }

    // 'slow' is before the midpoint in the list, so split it in two// at that point.

    *frontRef = source;

    *backRef = slow->next;

    slow->next = NULL;

    }}

  • 8/6/2019 [Huong Dan Tieng Viet] Cac Van de Voi DSLK

    20/30

    More information: www.itspiritclub.net Translater: huahongquan2007

    20

    Do danh sch c sp xp, chng ta c th duyt xung danh sch v so snh cc node lin k. Khi cc node lin kging nhau, xa ci th hai.

    Code ca MoveNode() thi tng tnh code ca Push(). N th ngn v chthay i mt cp con tr - nhngn kh phc tp. Hy th v hnh v m phng.

    Cc tip cn n gin nht l duy qua danh sch ngun v dng MoveNode() ko cc node ra khi ngun vlun phin t n vo a v b. Phn k l duy nht l cc node sth tngc li so vi danh sch gc.

    // Remove duplicates from a sorted list

    void RemoveDuplicates(struct node* head) {

    struct node* current = head;

    if (current == NULL) return; // do nothing if the list is empty

    // Compare current node with next node

    while(current->next!=NULL) {

    if (current->data == current->next->data) {

    struct node* nextNext = current->next->next;

    free(current->next);

    current->next = nextNext;

    }

    else {

    current = current->next; // only advance if no deletion

    }

    }

    }

    void MoveNode(struct node** destRef, struct node** sourceRef) {

    struct node* newNode = *sourceRef; // the front source nodeassert(newNode != NULL);

    *sourceRef = newNode->next; // Advance the source pointernewNode->next = *destRef; // Link the old dest off the new node*destRef = newNode; // Move dest to point to the new node

    }

  • 8/6/2019 [Huong Dan Tieng Viet] Cac Van de Voi DSLK

    21/30

    More information: www.itspiritclub.net Translater: huahongquan2007

    21

    AlternatingSplit()

    AlternatingSplit() Using Dummy Nodes

    y l mt cch tip cn thay th m n xy dng cc hm con trong th t ging nh danh sch gc. M nguns dng mt node u dummy tm cho danh sch a v b. Mi danh sch con c mt con trtail tr ti node cuicng ca n bng cch , node mi c thc ni thm vo ui ca mi danh sch mt cch d dng. Node dummyth hu dng trong trng trng hp ny v chng ta tm v c cp pht trong stack. Mt cch thay th, k thuttham chiu cc b ( local references) c thdng loi b cc node dummy( xem phn 1 bit thm chi tit).

    void AlternatingSplit(struct node* source,

    struct node** aRef, struct node** bRef) {

    struct node* a = NULL; // Split the nodes to these 'a' and 'b' lists

    struct node* b = NULL;

    struct node* current = source;

    while (current != NULL) {

    MoveNode(&a, &current); // Move a node to 'a'

    if (current != NULL) {MoveNode(&b, &current); // Move a node to 'b'

    }

    }

    *aRef = a;

    *bRef = b;

    }

    void AlternatingSplit2(struct node* source,

    struct node** aRef, struct node** bRef) {

    struct node aDummy;

    struct node* aTail = &aDummy; // points to the last node in 'a'

    struct node bDummy;struct node* bTail = &bDummy; // points to the last node in 'b'

    struct node* current = source;

    aDummy.next = NULL;

    bDummy.next = NULL;

    while (current != NULL) {

    MoveNode(&(aTail->next), &current); // add at 'a' tail

    aTail = aTail->next; // advance the 'a' tail

    if (current != NULL) {

    MoveNode(&(bTail->next), &current);

    bTail = bTail->next;

    }

    }

    *aRef = aDummy.next;

    *bRef = bDummy.next;}

  • 8/6/2019 [Huong Dan Tieng Viet] Cac Van de Voi DSLK

    22/30

    More information: www.itspiritclub.net Translater: huahongquan2007

    22

    Di y l bn gii php ring bit. Xem phn 1 bit thm v dummy node v local references.

    SuffleMerge() Dummy Node Not Using MoveNode()

    SuffleMerge() Dummy Node Using MoveNode()

    Tng tnh trn nhng s dng hm MoveNode()

    struct node* ShuffleMerge(struct node* a, struct node* b) {

    struct node dummy;

    struct node* tail = &dummy;

    dummy.next = NULL;

    while (1) {

    if (a==NULL) { // empty list cases

    tail->next = b;

    break;

    }

    elseif (b==NULL) {

    tail->next = a;

    break;

    }

    else { // common case: move two nodes to tailtail->next = a;

    tail = a;

    a = a->next;

    tail->next = b;

    tail = b;b = b->next;

    }

    }

    return(dummy.next);

    }

    struct node* ShuffleMerge(struct node* a, struct node* b) {

    struct node dummy;

    struct node* tail = &dummy;

    dummy.next = NULL;

    while (1) {

    if (a==NULL) {

    tail->next = b;

    break;

    }

    elseif (b==NULL) {

    tail->next = a;

    break;

    }

    else {MoveNode(&(tail->next), &a);

    tail = tail->next;

    MoveNode(&(tail->next), &b);

    tail = tail->next;

    }

    }

    return(dummy.next);}

  • 8/6/2019 [Huong Dan Tieng Viet] Cac Van de Voi DSLK

    23/30

    More information: www.itspiritclub.net Translater: huahongquan2007

    23

    SuffleMerge() Local References

    Dng tham chiu cc b(local references) loi b cc dummy node

    SuffleMerge() Recursive

    Gii php quy th sc tch hn c, nhng n c th khng ph hp cho m ngun thng mi v n dng khng gianspace tng ng vi di ca danh sch.

    struct node* ShuffleMerge(struct node* a, struct node* b) {

    struct node* result = NULL;

    struct node** lastPtrRef = &result;

    while (1) {

    if (a==NULL) {

    *lastPtrRef = b;

    break;

    }

    elseif (b==NULL) {

    *lastPtrRef = a;

    break;

    }

    else {

    MoveNode(lastPtrRef, &a);

    lastPtrRef = &((*lastPtrRef)->next);

    MoveNode(lastPtrRef, &b);

    lastPtrRef = &((*lastPtrRef)->next);

    }

    }return(result);

    }

    struct node* ShuffleMerge(struct node* a, struct node* b) {

    struct node* result;struct node* recur;

    if (a==NULL) return(b); // see if either list is empty

    elseif (b==NULL) return(a);

    else {

    // it turns out to be convenient to do the recursive call first --// otherwise a->next and b->next need temporary storage.

    recur = ShuffleMerge(a->next, b->next);

    result = a; // one node from aa->next = b; // one from bb->next = recur; // then the rest

    return(result);

    }

    }

  • 8/6/2019 [Huong Dan Tieng Viet] Cac Van de Voi DSLK

    24/30

    More information: www.itspiritclub.net Translater: huahongquan2007

    24

    SortedMerge() Using Dummy Nodes

    K thut ny dng node dummy tm nh l node bt u ca danh sch kt qu. Con tr tail lun lun tr ti node cuicng ca danh sch kt qu nn ni node mi th n gin. Dummy node th hu dng v n l tm thi, n cp pht trong stack. Vng lp hot ng, loi b mt node khi a hoc b v thm n vo tail. Khi hon thnh, kt qu tr v ldummy.next.

    SortedMerge() Using Local References

    Gii php ny v cu trc th rt tng tnh trn, nhng n trnh dng node dummy. Thay vo , n duy tr con trstruct node **, lastPtrRef, n lun tr v con tr cui ca danh sch kt qu. iu ny gii quyt trng hp tng tnhnode dummy x l vi danh sch kt qu khi n rng.

    struct node* SortedMerge(struct node* a, struct node* b) {

    struct node dummy; // a dummy first node to hang the result onstruct node* tail = &dummy; // Points to the last result node --// so tail->next is the place to add// new nodes to the result.

    dummy.next = NULL;

    while (1) {

    if (a == NULL) { // if either list runs out, use the other list

    tail->next = b;

    break;

    }elseif (b == NULL) {

    tail->next = a;

    break;

    }

    if (a->data data) {

    MoveNode(&(tail->next), &a);

    }

    else {

    MoveNode(&(tail->next), &b);

    }

    tail = tail->next;

    }

    return(dummy.next);

    }

  • 8/6/2019 [Huong Dan Tieng Viet] Cac Van de Voi DSLK

    25/30

    More information: www.itspiritclub.net Translater: huahongquan2007

    25

    SortedMerge() Using Recursion

    Merge() l mt trong nhng vn quy p khi quy th r rng hn l code lp.

    struct node* SortedMerge2(struct node* a, struct node* b) {

    struct node* result = NULL;

    struct node** lastPtrRef = &result; // point to the last result pointer

    while (1) {

    if (a==NULL) {

    *lastPtrRef = b;

    break;

    }

    elseif (b==NULL) {

    *lastPtrRef = a;break;

    }

    if (a->data data) {

    MoveNode(lastPtrRef, &a);

    }

    else {

    MoveNode(lastPtrRef, &b);

    }

    lastPtrRef = &((*lastPtrRef)->next); // tricky: advance to point to// the next ".next" field

    }

    return(result);}

    struct node* SortedMerge3(struct node* a, struct node* b) {

    struct node* result = NULL;

    // Base cases

    if (a==NULL) return(b);elseif (b==NULL) return(a);

    // Pick either a or b, and recur

    if (a->data data) {

    result = a;

    result->next = SortedMerge3(a->next, b);

    }

    else {

    result = b;

    result->next = SortedMerge3(a, b->next);

    }

    return(result);

    }

  • 8/6/2019 [Huong Dan Tieng Viet] Cac Van de Voi DSLK

    26/30

    More information: www.itspiritclub.net Translater: huahongquan2007

    26

    tng ca MergeSort l : ct thnh cc danh sch nh, sp xp chng bng quy v trn hai danh sch c spxp vi nhau to thnh cu tr li.

    K thut l tin ti trong c hai danh sch v xy dng danh sch kt qu. Khi v tr current trong c hai danh schth ging nhau, thm mt node vo trong kt qu.Bng cch khai thc vic chai danh sch c sp xp, chng ta chcn i qua danh sch mt ln. Bng cch xy dng danh sch kt qu, c th dng c hai node dummy v local referencenh sau:

    void MergeSort(struct node** headRef) {

    struct node* head = *headRef;

    struct node* a;

    struct node* b;

    // Base case -- length 0 or 1

    if ((head == NULL) || (head->next == NULL)) {

    return;

    }

    FrontBackSplit(head, &a, &b); // Split head into 'a' and 'b' sublists

    // We could just as well use AlternatingSplit()MergeSort(&a); // Recursively sort the sublists

    MergeSort(&b);

    *headRef = SortedMerge(a, b); // answer = merge the two sorted lists together}

    // This solution uses the temporary dummy to build up the result list

    struct node* SortedIntersect(struct node* a, struct node* b) {

    struct node dummy;

    struct node* tail = &dummy;

    dummy.next = NULL;

    // Once one or the other list runs out -- we're done

    while (a!=NULL && b!=NULL) {

    if (a->data == b->data) {

    Push((&tail->next), a->data);

    tail = tail->next;

    a = a->next;

    b = b->next;

    }

    elseif (a->data < b->data) { // advance the smaller list

    a = a->next;}

    else {

    b = b->next;

    }

    }return(dummy.next);

  • 8/6/2019 [Huong Dan Tieng Viet] Cac Van de Voi DSLK

    27/30

    More information: www.itspiritclub.net Translater: huahongquan2007

    27

    // This solution uses the local reference

    struct node* SortedIntersect2(struct node* a, struct node* b) {

    struct node* result = NULL;

    struct node** lastPtrRef = &result;

    // Advance comparing the first nodes in both lists.

    // When one or the other list runs out, we're done.

    while (a!=NULL && b!=NULL) {

    if (a->data == b->data) { // found a node for the intersection

    Push(lastPtrRef, a->data);

    lastPtrRef = &((*lastPtrRef)->next);a=a->next;

    b=b->next;

    }

    elseif (a->data < b->data) { // advance the smaller list

    a=a->next;

    }

    else {

    b=b->next;

    }

    }

    return(result);}

  • 8/6/2019 [Huong Dan Tieng Viet] Cac Van de Voi DSLK

    28/30

    More information: www.itspiritclub.net Translater: huahongquan2007

    28

    Gii php u tin l dng k thut Push vi sthay i con tr bng tay trong vng lp. Gii php ny kh l mnh nuchng ta cn phi lu gi tr ca con tr current ->next u vng lp khi thn ca vng lp sghi con tr.

    Mt bin th s dng hm MoveNode()

    /*

    Iterative list reverse.Iterate through the list left-right.Move/insert each node to the front of the result list --

    like a Push of the node.*/

    staticvoid Reverse(struct node** headRef) {

    struct node* result = NULL;

    struct node* current = *headRef;

    struct node* next;

    while (current != NULL) {

    next = current->next; // tricky: note the next nodecurrent->next = result; // move the node onto the result

    result = current;

    current = next;

    }*headRef = result;}

    staticvoid Reverse2(struct node** headRef) {

    struct node* result = NULL;

    struct node* current = *headRef;

    while (current != NULL) {

    MoveNode(&result, &current);

    }

    *headRef = result;}

  • 8/6/2019 [Huong Dan Tieng Viet] Cac Van de Voi DSLK

    29/30

    More information: www.itspiritclub.net Translater: huahongquan2007

    29

    Cui cng y l k thut front-middle-back

    C l phn kh nht l nm bt c khi nim ca RecursiveReverse(&rest). Hy v hnh m phng hiucch hm hot ng.

    Gii php km hiu qul o nhng ph t n-1 cui ca danh sch, v sau duyt xung tt c xung ti tailmi v t node head c . Gii php th rt l chm so vi trn m n ly node u ng v tr m khng cn vnglp thm.

    // Reverses the given linked list by changing its .next pointers and// its head pointer. Takes a pointer (reference) to the head pointer.

    void Reverse(struct node** headRef) {

    if (*headRef != NULL) { // special case: skip the empty list

    /*Plan for this loop: move three pointers: front, middle, backdown the list in order. Middle is the main pointer running

    down the list. Front leads it and Back trails it.For each step, reverse the middle pointer and then advance allthree to get the next node.*/struct node* middle = *headRef; // the main pointerstruct node* front = middle->next; // the two other pointers (NULL ok)

    struct node* back = NULL;

    while (1) {

    middle->next = back; // fix the middle nodeif (front == NULL) break; // test if doneback = middle; // advance the three pointers

    middle = front;

    front = front->next;

    }*headRef = middle; // fix the head pointer to point to the new front

    }

    }

    void RecursiveReverse(struct node** headRef) {

    struct node* first;

    struct node* rest;

    if (*headRef == NULL) return; // empty list base casefirst = *headRef; // suppose first = {1, 2, 3}rest = first->next; // rest = {2, 3}if (rest == NULL) return; // empty rest base caseRecursiveReverse(&rest); // Recursively reverse the smaller {2, 3} case

    // after: rest = {3, 2}first->next->next = first; // put the first elem on the end of the listfirst->next = NULL; // (tricky step -- make a drawing)*headRef = rest; // fix the head pointer

    }

  • 8/6/2019 [Huong Dan Tieng Viet] Cac Van de Voi DSLK

    30/30

    More information: www.itspiritclub.net Translater: huahongquan2007

    Nu cc bn c kin ng gp hoc mun tham gia dch ti liu vi chng ti, ccbn hy lin h nhm itspirit qua ym: whereareyou_sweetie

    Xin chn thnh cm n!