归并排序
核心思想:
是分治算法
的典型应用,归并排序中的来说就两步分
:把序列分成左右子序列,左右子序列又细分成各自的左右子序列,直到左右子序列都各只有一个
(递归实现)治:
对分好的子序列分别进行合并排序,这里排序的方法是定义两个哨兵,左哨兵指向左子序列的首元素,右哨兵指向右子序列的首元素,然后两者指向的值进行比较,谁小,则谁先存入新数组,直到左右序列都存完
时间复杂度:
- 最好最差均为
O(nlogn)
- 辅助空间为
O(n)
- 稳定性
:稳定
- 最好最差均为
图解
递归实现代码
#include <iostream>
void merge(int arr[],int left,int right,int mid,int temp[]){//合(并)
int k=0,t=0;
int i=left;
int j=mid+1;
while(i<=mid&&j<=right){//若左右哨兵有一方越界,则此while雪崩
if(arr[i]<arr[j]){
temp[k++]=arr[i++];
}else{
temp[k++]=arr[j++];
}
}
while(i<=mid){//剩下左哨兵,则左边开门送连环抱
temp[k++]=arr[i++];
}
while(j<=right){//剩下右哨兵,则右边开门送连环抱
temp[k++]=arr[j++];
}
while(left<=right){//把排好序的临时数组复制到arr中
arr[left++]=temp[t++];
}
}
void sort(int arr[],int left,int right,int temp[]){//分(归)
if(left<right){//当left==right时(即分到只有一个元素时,结束)
int mid=(left+right)/2;//把数组分成[left...mid]和[mid+1...right]两部分
sort(arr,left,mid,temp);//分左半部分
sort(arr,mid+1,right,temp);//分右半部分
merge(arr,left,right,mid,temp);//把分好的左右部分混合排好序
}
}
int main(int argc, char** argv) {
int temp[100];
int arr[]={9,8,7,6,4,2,5,3,2,1};
sort(arr,0,9,temp);
for(int i=0;i<10;i++){
printf("%d ",arr[i]);
}
return 0;
}
注:本文所用图为dreamcatcher-cx大神的博客