归并排序的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
- 归并排序的3种实现
- 归并排序的实现
- 归并排序的实现
- 归并排序的实现
- 归并排序的实现
- 归并排序的实现
- 归并排序的实现
- 归并排序的实现
- 归并排序的实现
- 归并排序的实现
- 归并排序的实现
- 归并排序的实现
- 归并排序的实现
- 归并排序的实现
- 归并排序的实现
- 归并排序的实现
- 归并排序的实现
- 归并排序的实现
- window10下qt creator下自定义并使用 基于Qt5.3.2
- 【面试题】判断链表中是否有环
- unity中利用mesh动态创建墙体
- 递归遍历整个目录的代码
- 二叉树的构建和三种遍历算法 (递归实现)
- 归并排序的3种实现
- 面向对象
- 学习笔记--Ajax:JSON格式返回数据
- Spring4.1.4 bean的加载与赋值
- 21. Merge Two Sorted Lists
- 读C#线程及线程池笔记
- 对HTTPCONNECTION的理解
- jsp的3个编译指令,7个动作指令,9个内置对象
- "remote:error:refusing to update checked out branch:refs/heads/master"的解决办法