提醒一下自己,面试的时候可以写成template。
冒泡排序(稳定)
冒泡排序是稳定的。基本的冒泡排序的比较次数与数组是否有序无关,但是数据交换次数与数组是否有序有关。基本冒泡排序时间复杂度为o(n^2)。改进型的冒泡排序最好的时间复杂度为o(n),比较次数与数组初始是否有序有关,交换次数也有关。
(1)改进型前向冒泡排序,即循环一次,冒出一个最大值到末尾。
void BubbleSortForward(int arr[],int len) { int i,j; if(!arr||len<=0) throw new exception("NULL Array"); for(i = 0;i<len -1;++i){ bool flag = false; for(j = 0;j<len - 1 -i;++j){ if(arr[j]>arr[j+1]){//保证稳定性无等号 swap(arr[j],arr[j+1]); flag = true; } } if(!flag)break; } }
(2)改进型后向冒泡排序,即循环一次,冒出一个最小值到数组前面。
void BubbleSortBackward(int arr[],int len) { int i,j; bool flag; if(!arr||len<=0) throw new exception("NULL Array"); for(i = 0;i<len -1;++i){ flag = false; for(j = len-1;j > i;--j){ if(arr[j]<arr[j-1]){ swap(arr[j],arr[j-1]); flag = true; } } if(!flag)break; } }
选择排序(稳定)
选择排序每次将最小的选择出来放在前面,比较次数与数组是否有序无关,但是元素移动次数与数组是否有序有关,选择排序时间复杂度o(n^2)
int SelectionSort(int arr[],int len) { if(!arr||len<=0) throw new exception("NULL Array"); for(int i =0;i<len-1;i++){ int k = i; for(int j=i+1;j<len;++j) if(arr[j]<arr[k])k = j; if(k!=i)swap(arr[k],arr[i]); } }
插入排序(稳定)
插入排序最好的时间复杂度为o(n),只需要比较n-1次,插入排序的比较次数数组是否有序有关很大的关系。插入排序对于规模很小的数据排序很有效。
(1)直接插入排序
void InsertSort(int arr[],int start,int end) { if(!arr||start<0||start>end) throw new exception("NULL Array"); for(int i=start+1;i<=end;i++){ if(arr[i]<arr[i-1]){ int base = arr[i]; int j = i; while(j>=1&&arr[j-1]>base){//等号不取 arr[j] = arr[j-1]; j--; } arr[j] = base; } } }
(2)折半插入排序(二分搜索)
void BinaryInsertSort(int arr[],int start,int end) { if(!arr||start<0||start>end) throw new exception("NULL Array"); for(int i = start+1;i<=end;++i ){ int low = start; int high = i - 1; int base = arr[i]; while(low<=high){ int mid = (high - low>>1)+low; if(base<arr[mid])high = mid-1; else low = mid + 1;//包含等于 } for(int k = i;k>low;k--){ arr[k] = arr[k-1]; } arr[low] = base; } }
希尔排序(不稳定)
shell排序是在插入排序的基础上改进的。shell排序将一个数组分成gap个子序列,所有元素距离为gap的元素放在同一个子序列中,每个子序列中分别实行插入排序。每迭代一次,gap缩小。
gap = right - left +1;
迭代一次:gap = gap/3 + 1;
gap的取法有讲究,本来gap = gap/2+1,但是在这种取法方式中,要到最后一步奇数位置的元素才能和偶数元素位置比较,这样效率低。元素比较次数和移动次数:n^1.25~1.6n^1.25
void ShellSort(int arr[],int start,int end) { if(!arr||start<0||start>end) throw new exception("NULL Array"); int gap = end - start + 1; while(gap>1){ gap = gap/3 + 1; for(int i = start+gap;i<=end;++i ){ if(arr[i]<arr[i-gap]){ int base = arr[i]; int j = i; while(j>=gap&&arr[j-gap]>base){ arr[j] = arr[j-gap]; j -= gap; } arr[j] = base; } } } } 注:插入的排序的1被替换为gap了,有没有。