單鏈表的快速排序演算法及其實現
阿新 • • 發佈:2018-12-25
今天聽同學面友錄說道單鏈表是否可以用快速排序演算法,想起自己面百度一面的時候面試官也面到這個問題,由於本人是個小菜鳥,所以花了一個下午的時間整理了一下。
演算法思想:對於一個連結串列,以head節點的值作為key,然後遍歷之後的節點,可以得到一個小於key的連結串列和大於等於key的連結串列;由此遞迴可以對兩個連結串列分別進行快速。這裡用到了快速排序的思想即經過一趟排序能夠將小於key的元素放在一邊,將大於等於key的元素放在另一邊;面試回答:如果面試官問快速排序是否適合單鏈表,答案當然是不適合;但是如果問單鏈表可不可以用快速排序,答案當然是肯定的;下面貼出一段拙劣的程式碼,希望大家修正!
code:
struct LinkNode{ int value; LinkNode* next; LinkNode(): value(0), next(NULL) {}; }; void Quicksort(LinkNode* &head, LinkNode* &end){ LinkNode *head1, *head2, *end1, *end2; /* 記錄每次分割後前後兩個連結串列的頭尾節點*/ head1 = head2 = end1 = end2 = NULL; if( head == NULL ) return; //如果遍歷的當前節點為空,返回 LinkNode *p, *pre1, *pre2; /*用於遍歷連結串列將連結串列中的元素分成大於key和小於key兩個部分*/ p = pre1 = pre2 = NULL; int key = head->value; p = head->next; head->next = NULL; //將head的值孤立出來 while( p != NULL ) { //小於key的連結串列 if ( p->value < key ){ if( !head1 ) { head1 = p; pre1 = p; } else{ pre1->next = p; pre1 = p; } p = p->next; pre1->next = NULL; } //大於等於key的連結串列 else{ if( !head2 ) { head2 = p; pre2 = p; } else { pre2->next = p; pre2 = p; } p = p->next; pre2->next = NULL; } } end1 = pre1; end2 = pre2; /*產生新連結串列的首尾節點*/ //對左右兩個連結串列進行遞迴快排 Quicksort(head1, end1); Quicksort(head2, end2); //從遞迴棧返回的時候,將key節點和左右兩個連結串列連起來 //左右連結串列都存在 if( end1 && head2){ end1->next = head; head->next = head2; head = head1; end = end2;} //只有左連結串列 else if(end1) { end1->next = head; end = head; head = head1; } //只有右連結串列 else if(head2){ head->next = head2; end = end2;} }