用歸併排序對鏈表進行排序

來源:互聯網
上載者:User

        當我們需要對鏈表進行排序時,由於不能對它的元素進行隨機訪問,所以更適合使用歸併排序,大名鼎鼎的快速排序用到鏈表上,效率也很低,原因還是在於不能對鏈表中的元素進行隨機訪問,同理,採用堆排序更是不可能的事情。

        演算法具體實現時需要一個指向前端節點(鏈表的第一個節點,鏈表中不包含額外的一個節點來作前端節點)的指標,這是因為在演算法實現的時候,不大可能第一個節點正好就是所有元素中最小的一個,則鏈表的前端節點會改變,因此我們需要一個指向前端節點的指標來儲存不斷變化的前端節點。

演算法思想:

MergeSort(headRef)
1) If head is NULL or there is only one element in the Linked List    then return.2) Else divide the linked list into two halves.      FrontBackSplit(head, &a, &b); /* a and b are two halves */3) Sort the two halves a and b.      MergeSort(a);      MergeSort(b);4) Merge the sorted a and b (using SortedMerge() discussed here)   and update the head pointer using headRef.     *headRef = SortedMerge(a, b);
程式碼範例:
#include <stdio.h>#include <stdlib.h>/*Link list node*/struct node{int data;struct node* next;};/*function prototype */struct node* SortedMerge(struct node* a, struct node* b);void FrontBackSplit(struct node* source, struct node** frontRef, struct node** backRef);/*sorts the linked list by changing next pointers(not data) */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;}/*Split head into 'a' and 'b' sublists */FrontBackSplit(head, &a, &b);/*Recursively sort the sublists */MergeSort(&a);MergeSort(&b);/* answer = merge the two sorted lists together */*headRef = SortedMerge(a, b);}struct node* SortedMerge(struct node* a, struct node* b){struct node* result = NULL;/* Base cases */if(a == NULL)return (b);else if(b == NULL)return (a);/* Pick either a or b recur */if(a->data <= b->data){result = a;result->next = SortedMerge(a->next, b);}else{result = b;result->next = SortedMerge(a, b->next);}return (result);}/* UTILITY FUNCTIONS *//* Split the nodes of the given list into front and back halves,    and return the two lists using the references parameters.    If the length is odd, the extra node shold go in the front list.    Uses the fast/slow pointer strategy. */void FrontBackSplit(struct node* source, struct node** frontRef, struct node** backRef){struct node* fast;struct node* slow;if(source == NULL || source->next == NULL){*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;}}*frontRef = source;*backRef = slow->next;slow->next = NULL;}}/*Function to print nodes in a given linked list*/void printList(struct node* node){while( node != NULL ){printf("%d  ", node->data);node = node->next;}}/* Function to insert a node at the begining of the linked list*/void push(struct node** head_ref, int new_data){/*allocate node*/struct node* new_node = (struct node*)malloc(sizeof(struct node));/*put in the data*/new_node->data = new_data;/*link the old list off the new node*/new_node->next = (*head_ref);/*move the head to point to the new node*/(*head_ref) = new_node;}/* Drier program to test above functions*/int main(){/* Start with the empty list */struct node* res = NULL;struct node* a = NULL;/* Let us create a unsorted linked lists to test the functions   Created lists shall be a: 2->3->20->5->10->15 */push(&a, 15);push(&a, 10);push(&a, 5);push(&a, 20);push(&a, 3);push(&a, 2); /* Sort the above created Linked List */MergeSort(&a);printf("\n Sorted Linked List is: \n");printList(a);           return 0;}

時間複雜度為O(nLogn)。

貌似MergeSort的時間複雜度為O(nLogn),Split的時間複雜度也為O(nLogn)?當然了,總的時間複雜度還是O(nLogn),但是肯定沒有對數組進行歸併排序快。
原文地址:http://www.geeksforgeeks.org/archives/7740

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.