选择排序
遍历数组记录最小值下标,与第一项依次交换。
for(int i=1;i<n;i++){
int count=i;
for(int j=i+1;j<=n;j++){
if(num[count]>num[j])count=j;
}
swap(num[count],num[i]);
}
冒泡排序
将大气泡换到后面
for(int i=n;i>=1;i--){
for(int j=1;j<i;j++){
if(num[j]>num[j+1])swap(num[j],num[j+1]);
}
}
插入排序
将第j个和前一个比较
for(int i=2;i<=n;i++){
for(int j=i-1;j>=1&&num[j]>num[j+1];j--){
swap(num[j],num[j+1]);
}
}
快速排序
选择最后一个数字
1.0 荷兰国旗问题思想,分两块 , 一次处理一个数m
2.0 荷兰国旗问题思想,分三块 ,一次处理多个数m
3.0 随机快排
- acwing&code
void quick_sort(int arr[],int l,int r){ if(l>=r)return; int i=l-1,j=r+1,x=arr[l+((r-l)>>1)]; while(i<j){ do i++;while(arr[i]<x); do j--;while(arr[j]>x); //总写错arr[i] if(i<j)swap(arr[i],arr[j]); //总忘写if } quick_sort(arr,l,j); quick_sort(arr,j+1,r); }
- 荷兰国旗&快排code <-传送门
public static void quickSort(int[] arr, int l, int r) { if (l < r) { swap(arr, l + (int) (Math.random() * (r - l + 1)), r); int[] p = partition(arr, l, r); quickSort(arr, l, p[0] - 1); quickSort(arr, p[1] + 1, r); } } public static int[] partition(int[] arr, int l, int r) { int less = l - 1; int more = r; while (l < more) { if (arr[l] < arr[r]) { swap(arr, ++less, l++); } else if (arr[l] > arr[r]) { swap(arr, --more, l); } else { l++; } } swap(arr, more, r); return new int[] { less + 1, more }; } //作者:左程云
归并排序
时间复杂度O(N*logN),额外空间复杂度O(N)
void merge_sort(int arr[],int l,int r){
if(l>=r)return;
int mid = l+r>>1;
merge_sort(arr,l,mid);merge_sort(arr,mid+1,r);
int k=0,i=l,j=mid+1;
while(i<=mid&&j<=r) //比较小的存起来
if(arr[i]>arr[j])tmp[k++]=arr[j++];
else tmp[k++]=arr[i++];
while(i<=mid)tmp[k++]=arr[i++]; //再存起来剩下的的
while(j<=r)tmp[k++]=arr[j++];
for(i=l,j=0;i<=r;i++,j++)arr[i]=tmp[j]; //还回去
}
堆排序
底层是数组结构,思维中是一颗完全二叉树
- 大根堆:所有根节点>=左右孩子
- 小根堆:所有根节点<=左右孩子
- add 往数组最后一个位置+1
- heapadd 和父节点比较,交换
- heapify
完全二叉树
从0开始: 左孩子=2i+1 右孩子=2i+2 父=(i-1)/2
从1开始: 左孩子=2i 右孩子=2i+1 父=i/2
priority_queue<int > q1;//大
priority_queue<int,vector<int>,greater<int> > q2;//小
*i 右孩子=2*i+1 父=i/2
```cpp
priority_queue<int > q1;//大
priority_queue<int,vector<int>,greater<int> > q2;//小