归并排序的3种实现

来源:互联网 发布:win10关闭网络唤醒 编辑:程序博客网 时间:2024/05/18 07:22

归并排序适用于外部排序,是一种稳定的排序。算法很很好的体现了分治法的思想。
时间复杂度O(nlogn)(最好最坏平均都是它)
空间复杂度O(n) (如果使用的是链表,空间复杂度为O(1))

数组递归实现:

void Merge(int* arr,int* tmp,int left,int right,int rightEnd){    int leftEnd = right-1;    int start = left;    int len = rightEnd - left + 1;    while (left<=leftEnd && right<=rightEnd)    {        if (arr[left] > arr[right]){            tmp[start++] = arr[right++];        }        else{            tmp[start++] = arr[left++];        }    }    while (left <= leftEnd)    {        tmp[start++] = arr[left++];    }    while(right<=rightEnd){        tmp[start++] = arr[right++];    }    for (int i = 0; i < len; i++, rightEnd--){        arr[rightEnd] = tmp[rightEnd];    }}void split(int* arr,int* tmp,int left,int rightEnd){    if (left < rightEnd){        int center = (rightEnd + left) / 2;        split(arr, tmp, left, center);        split(arr, tmp, center + 1, rightEnd);        Merge(arr, tmp, left, center + 1, rightEnd);    }}void Merge_Sort(int* arr,int len){    int *tmp = (int*)malloc(sizeof(int)*len);    split(arr,tmp,0,len-1);    free(tmp);}

数组非递归实现:

void Merge(int* arr,int* tmp,int left,int right,int rightEnd){    int leftEnd = right - 1;    int start = left;    while (left <= leftEnd && right <= rightEnd){        if (arr[left] > arr[right]){            tmp[start++] = arr[right++];        }        else{            tmp[start++] = arr[left++];        }    }    while (left <= leftEnd){        tmp[start++] = arr[left++];    }    while (right <= rightEnd){        tmp[start++] = arr[right++];    }}void MergeSort(int* arr,int* tmp,int n,int length)//length当前有序子列的长度{    int i;    for (i = 0; i <= n - 2 * length; i += 2 * length){        Merge(arr,tmp,i,i+length,i+2*length-1);    }    //最后剩下两个子列,进行归并    if (i + length < n){        Merge(arr,tmp,i,i+length,n-1);    }    else{//只剩最后一个子列,不能成对        for (int j = i; j < n; j++){            tmp[j] = arr[j];        }    }}void Merge_Sort(int* arr,int n){    int lenght = 1;    int* tmp = (int *)malloc(sizeof(int)*n);    while (lenght < n){        MergeSort(arr,tmp,n,lenght);        lenght *= 2;        MergeSort(tmp,arr,n,lenght);        lenght *= 2;    }    free(tmp);}

链表实现:

void Merge(ListNode* &left,ListNode* right){    ListNode* tmp = NULL;    ListNode* head = new ListNode(0);    head->next = left;    ListNode* leftPre = head;    while (left != NULL && right != NULL){        if (left->val > right->val){            tmp = right->next;            leftPre->next = right;            right->next = left;            leftPre = leftPre->next;            right = tmp;        }        else{            leftPre = left;            left = left->next;        }    }    while (right!= NULL){        leftPre->next = right;        leftPre = leftPre->next;        right = right->next;    }    left = head->next;    delete head;}//对链表进行分割void split(ListNode* &left,ListNode* &right,ListNode* pHead){    ListNode* low = pHead;    ListNode* high = pHead;    while (high->next != NULL && high->next->next != NULL){        low = low->next;        high = high->next->next;    }    left = pHead;    right = low->next;    low->next = NULL;}void Merge_Sort(ListNode* &pHead){    if (pHead == NULL || pHead->next==NULL){        return;    }    ListNode* left = NULL;    ListNode* right = NULL;    split(left,right,pHead);    Merge_Sort(left);    Merge_Sort(right);    Merge(left,right);    pHead = left;//更新pHead}
1 0
原创粉丝点击