# 排序
几个口诀:
1. 考研复习痛苦啊,情绪不稳定(不稳定算法),** 快(快速)些(希尔)选(简单选择)一堆(堆)** 好友来聊天吧。
2. 时间复杂度计算:
- 快(快速)些(希尔)以 nlogn 的速度归 (归并) 队(堆)
- 基数排序:O (d (n+rd))
- 快速排序最坏的情况下(有序):O(n²)
- 除此之外的其他算法都是 O (n²)
3. 空间复杂度的计算:
- 快:O(log2n)
- 归:O (n)
- 基数:O (rd)
- 其他均为 O (1)
# 折半插入
| |
| |
| |
| |
| void BibleSort(int A[],int n){ |
| int i,j; |
| int mid; |
| int temp; |
| int low,height; |
| for(i = 1;i<n;i++){ |
| temp = A[i]; |
| low = 0; |
| height = i-1; |
| while(low<height){ |
| mid =(low+height)/2; |
| |
| if(A[mid]>A[i]){ |
| |
| height = mid-1; |
| }else{ |
| low = mid+1; |
| } |
| } |
| |
| for(j = i-1;j>height;j--){ |
| A[j+1] = A[j]; |
| } |
| A[height+1] = temp; |
| } |
| |
| } |
# 冒泡排序
| |
| |
| |
| |
| void BubbleSort(int A[],int n){ |
| int i,j,k; |
| int temp; |
| for(i = 0;i<n;i++){ |
| bool flag = false; |
| for(j = n-1;j>i;j--){ |
| if(A[j]<A[j-1]){ |
| temp = A[j-1]; |
| A[j-1] = A[j]; |
| A[j] = temp; |
| flag = true; |
| } |
| } |
| } |
| if(flag == false){ |
| return; |
| } |
| } |
# 双向冒泡排序
| |
| |
| |
| |
| 目的都是为了:优化算法,提升效率从第一个位置开始没有发生交换, |
| 说明后座都已经被对应实力的大数占完,不必再为大数找后座了 |
| */ |
| |
| |
| |
| void swap(int x,int y){ |
| int temp; |
| temp = x; |
| x = y; |
| y = temp; |
| } |
| void DoubleBubbleSort(int A[],n){ |
| int low = 0,height = n-1; |
| int i = 0,j = 0; |
| bool flag = true; |
| while(low<height&&flag){ |
| for(i = low;i<height;i++){ |
| if(A[i]>A[i+1]){ |
| swap(A[i],A[i+1]); |
| flag = true; |
| } |
| } |
| height--; |
| for(j = height;j>low;j--){ |
| if(A[j]<A[j-1]){ |
| swap(A[j],A[j-1]); |
| flag = true; |
| } |
| } |
| low++; |
| } |
| } |
# 简单选择排序
| |
| |
| |
| |
| |
| void EasySelect(int A[],int len){ |
| int i = 0; |
| int min = 0; |
| for(i = 0;i<len-1;i++){ |
| min = i; |
| for(int j = i+1;j<len;j++){ |
| if(A[j]<A[min]){ |
| min = j; |
| } |
| } |
| } |
| |
| if(min!=i){ |
| int temp = A[i]; |
| A[i] = A[min]; |
| A[min] = temp; |
| } |
| } |
# 快速排序
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| void FastSort(int A[],int n,int low,int height){ |
| int i = low; |
| int j = height |
| int baseElem = A[low]; |
| while(low<height){ |
| |
| while(baseElem>=A[j-1]){ |
| j--; |
| } |
| |
| if(i<j){ |
| A[i] = A[j]; |
| |
| j--; |
| } |
| while(baseElem<A[j-1]){ |
| i++; |
| } |
| |
| if(i<j){ |
| A[j] = A[i]; |
| } |
| A[i] = baseElem; |
| } |
| } |
# 直接插入排序
| |
| |
| |
| |
| |
| |
| void InsertSort(int A[],int length){ |
| int i,j; |
| int guard = 0; |
| for(i = 1;i<=n;i++){ |
| if(A[i]<A[i-1]){ |
| guard = A[i];s |
| for(j = i-1;guard<A[j];--j){ |
| A[j+1] = A[j]; |
| } |
| A[j+1] = guard; |
| |
| |
| } |
| } |
| } |
# 归并排序
| |
| |
| |
| |
| |
| |
| void MergeSort(int low,int height,int A[]){ |
| if(low<height){ |
| int mid = (low+height)/2; |
| MergeSort(low,mid,A[]); |
| MergeSort(mid+1,height,A[]); |
| Merge(low,mid,height,A[]); |
| } |
| } |
| |
| void Merge(int low,int height,int mid,int A[]){ |
| int *B = (int *)malloc(sizeof(int)*n+1); |
| for(int k = low;i<height;i++){ |
| B[k] = A[k]; |
| } |
| |
| |
| |
| |
| for(int i = low,int j = mid+1,k = i;j<height&&i<mid;k++){ |
| if(B[i]>B[j]){ |
| A[k] = B[j++]; |
| }else{ |
| A[k] = B[i++]; |
| } |
| } |
| |
| while(i<=mid){ |
| |
| A[k++] = B[i++]; |
| } |
| |
| while(j<=height){ |
| |
| A[k++] = B[j++]; |
| } |
| } |
# 希尔排序
| |
| |
| |
| |
| |
| |
| |
| void ShellSort(int A[],int n){ |
| int i,j; |
| int d = n/2; |
| int temp; |
| for(d = n/2;d>=1;d = d/2){ |
| |
| for(i = d;i<n;i++){ |
| temp = A[i]; |
| j = i-d; |
| |
| |
| while(j>0&&temp<A[j]){ |
| A[j+d] = A[j]; |
| j = j-d; |
| } |
| A[j+d] = temp; |
| |
| } |
| } |
| } |
# 堆排序
# 小根堆
| |
| |
| void MinHeap(int Arr[],int len){ |
| for(int i = len/2;i>0;i--){ |
| createHeap(Arr,i,len); |
| } |
| } |
| |
| void createHeap(int Arr[],int k,int len){ |
| |
| A[k] = A[0]; |
| for(int i = i*2;i<len;i++){ |
| if(i<len&&A[i]>A[i+1]){ |
| |
| i = i++; |
| } |
| if(A[0]<A[i]){ |
| |
| break; |
| }else{ |
| A[k] = A[i]; |
| k = i; |
| } |
| } |
| A[k] = A[0]; |
| |
| } |
| |
| void HeapSort(int Arr[],int len){ |
| |
| BuildMaxHeap(Arr,len); |
| for(int i = len;i>1;i--){ |
| |
| |
| |
| swap(A[i],A[1],Arr) |
| createHeap(Arr,1,i-1); |
| } |
| } |
| |
| void swap(int i,int j,int Arr[]){ |
| int temp = A[i]; |
| A[i] = A[j]; |
| A[j] = temp; |
| } |
# 大根堆
| |
| |
| |
| |
| |
| void MaxHeap(int Arr[],int len){ |
| |
| for(int i = len/2;i>0;i--){ |
| createHeap(Arr,i,len); |
| } |
| } |
| |
| void createHeap(int Arr[],int k,int len){ |
| |
| A[k] = A[0]; |
| for(int i = i*2;i<len;i++){ |
| |
| if(i<len&&A[i+1]>A[i]){ |
| |
| i++; |
| } |
| if(A[0]>A[i]){ |
| |
| break; |
| }else{ |
| |
| A[k] = A[i]; |
| k = i; |
| } |
| } |
| |
| A[k] = A[0] |
| } |
| |
| void HeapSort(int Arr[],int len){ |
| |
| BuildMaxHeap(Arr,len); |
| for(int i = len;i>1;i--){ |
| |
| |
| |
| swap(A[i],A[1],Arr) |
| createHeap(Arr,1,i-1); |
| } |
| } |
| |
| void swap(int i,int j,int Arr[]){ |
| int temp = A[i]; |
| A[i] = A[j]; |
| A[j] = temp; |
| } |
# 应用
| |
| |
| void OddFrontEven(int A[],int len){ |
| int i = 0; |
| int j = len-1; |
| while(i<j){ |
| while(i<j&&A[i]%2 !=0){ |
| i++; |
| |
| } |
| while(i<j&&A[j]%2 ==0){ |
| j--; |
| |
| } |
| if(i<j){ |
| int temp = A[j]; |
| A[j] = A[i]; |
| A[i] = temp; |
| } |
| i++; |
| j--; |
| } |
| } |
| |
| |
| |
| |
| |
| 我的方法不知道对不对<|>,先把答案的写出把 |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
# 简答题
1. 快速排序的基本思想以及他不适合用于什么场合
答:快速排序算法是基于分治策略的排序算法。
该方法的基本思想是:
- 先从数列中取出一个数作为基准数,记为 x。
- 分区过程,将不小于 x 的数全放到它的右边,不大于 x 的数全放到它的左边。(这样 key 的位置左边的没有大于 key 的,右边的没有小于 key 的,只需对左右区间排序即可)
- 再对左右区间重复第二步,直到各区间只有一个数
在关键字已经基本有序的情况下,快速排序法不能体现出其优越性