归并排序C++版

来源:互联网 发布:js给input设置属性 编辑:程序博客网 时间:2024/05/16 17:24

归并排序首先找中间节点。如果是链表,利用快慢指针寻找中间节点,如果是数组,直接使用(start+end)/2找到中间节点位置,链表版本中,需要O(1)的空闲复杂度去存一个头节点,而数组版本,需要O(N)的空间复杂度需要构造一个缓存数组存下所有节点。两种版本的实现时间复杂度都是O(N*logN)。下面看代码

数组版本:

/* 归并排序的空闲消耗比较大 */bool SortAlgorithms::mergeSort(int array[], int tempArray[], int left, int right){if(left==right)return false;int middle=(left+right)/2;mergeSort(array,tempArray,left,middle);mergeSort(array,tempArray,middle+1,right);merge(array,tempArray,left,right,middle);}void SortAlgorithms::merge(int array[], int tempArray[], int left, int right, int middle){for(int i=left;i<=right;i++){tempArray[i]=array[i];}int k=left;int i=left;int j=middle+1;while((i<=middle)&&(j<=right)){if(tempArray[i]>tempArray[j]){array[k]=tempArray[j];j++;k++;}else{array[k]=tempArray[i];i++;k++;}}while(i<=middle){array[k]=tempArray[i];i++;k++;}while(j<=right){array[k]=tempArray[j];j++;k++;}prt(array);}void SortAlgorithms::radixSort(){}void SortAlgorithms::prt(int *arr){for(int i=0;i<20;i++){cout<<" "<<arr[i];}cout<<endl;}

测试:

sort->mergeSort(waitingforSort,tempArray,0,19);sort->prt(waitingforSort);

链表版本:

#include "List.h"List::List() {// TODO Auto-generated constructor stub}List::~List() {// TODO Auto-generated destructor stub}void List::init(){/* for test, there is 11 nodes */head=(ListNode *)malloc(sizeof(ListNode));head->val=9;head->next=0;ListNode *node;for(int i=0;i<10;i++){node=(ListNode *)malloc(sizeof(ListNode));node->val=i;node->next=head->next;head->next=node;}l1=(ListNode *)malloc(sizeof(ListNode));l1->val=1;l1->next=0;for(int i=0;i<10;i++){node=(ListNode *)malloc(sizeof(ListNode));node->val=30-i*3;node->next=l1->next;l1->next=node;}l2=(ListNode *)malloc(sizeof(ListNode));l2->val=1;l2->next=0;for(int i=0;i<10;i++){node=(ListNode *)malloc(sizeof(ListNode));node->val=20-i*1;node->next=l2->next;l2->next=node;}}ListNode* List::getRoot(){return head;}/* * fast and slow pointer, it's great! divided into two parts. * 2*n+1: *   fast: n times reach 1+2*n *   slow: n times reach 1+n(last node in first list) * 2*n: *   fast: n-1 times reach 2*n-1 *   slow: n-1 times reach n(last node in first list) * */ListNode* List::findMiddle(ListNode *head){ListNode *fast=head;ListNode *slow=head;while(fast->next!=0&&fast->next->next!=0){fast=fast->next->next;slow=slow->next;}return slow;}ListNode *List::mergeTwoList(ListNode *left, ListNode *right){ListNode *ret=(ListNode *)malloc(sizeof(ListNode));ret->val=-1;ret->next=0;ListNode *r=ret;while(left!=0&&right!=0){if(left->val<right->val){ret->next=left;ret=left;left=left->next;}else{ret->next=right;ret=right;right=right->next;}}while(left!=0){ret->next=left;ret=left;left=left->next;}while(right!=0){ret->next=right;ret=right;right=right->next;}return r->next;}ListNode *List::sortList(ListNode *head){if(head==0||head->next==0)return head;ListNode *first=head;ListNode *middle=findMiddle(head);ListNode *second=middle->next;middle->next=0;ListNode *li1=sortList(first);ListNode *li2=sortList(second);return mergeTwoList(li1,li2);}void List::print(ListNode *h){ListNode *node=h;while(node!=0){cout<<" : "<<node->val;node=node->next;}cout<<endl;}

如果是排序多个已经排序的链表,可以都转换为排序两个,但是还有种应该更快的方法,采用一个排序的buffer。

(本文完)

0 0