【精简】排序算法总结

选择排序

遍历数组记录最小值下标,与第一项依次交换。

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;//小 

猜你喜欢

转载自blog.csdn.net/zhimeng_LQ/article/details/106952775