算法——排序

基础排序

冒泡排序

for(int i=0;i<arr.size()-1;i++)
  for(int j=0;j<arr.size()-1-i;j++)
     if(arr[j]>arr[j+1])
     swap(arr[j],arr[j+1]);

选择性排序

for(int i=0;i<arr.size();i++){
      int minIndex=i;
  for(int j=i+1;j<arr.size();j++)
     if(arr[minIndex]>arr[j])
     minIndex=j;
     swap(arr[i],arr[minIndex]);
     }

插入排序

for(int i=1;i<arr.size()-1;i++)
  for(int j=i;j>0;j--)
     if(arr[j-1]>arr[j])
        swap(arr[j],arr[j-1]);
     else
        break;

高级排序

归并排序


在这里插入图片描述

#include <iostream>
#include <algorithm>
#include <ctime>
#include <stdlib.h>



using namespace std;

//* VS不支持动态长度数组, 即不能使用 T aux[r-l+1]的方式申请aux的空间
    //* 使用VS的同学, 请使用new的方式申请aux空间
    //* 使用new申请空间, 不要忘了在__merge函数的最后, delete掉申请的空间:)
template<typename T>
void merge(T arr[], int l, int mid, int r){
     T *aux=new T[r-l+1];
     for(int i=l; i<r+1; i++)
     aux[i-l]=arr[i];
     int li=l;
     int ri=mid+1;
     for (int j=l; j<r+1; j++){
           if(li>mid) {
           arr[j]=aux[ri-l];
           ri++;
           }
           else if(ri>r){
           arr[j]=aux[li-l];
           li++;
           }
           else if(aux[li-l]>aux[ri-l]){
           arr[j]=aux[ri-l];
           ri++;
           }else{
           arr[j]=aux[li-l];
           li++;
           }
     }
   delete[] aux;  
}
template<typename T>
void _mergeSort(T arr[], int l, int r){
       if(l>=r) return;
       int mid=l+(r-l)/2;
       _mergeSort(arr, l, mid);
       _mergeSort(arr, mid+1, r);
       if(arr[mid]>arr[mid+1])
       merge(arr, l, mid, r);
}
template<typename T>
void mergeSort(T arr[], int n){
       if(n<2) return;
       _mergeSort(arr, 0, n-1);
}
int main() {

    // 测试1 一般性测试
    cout<<"Test for random array, size = "<<10<<", random range [0, "<<10<<"]"<<endl;
    
	int arr2[10] ={1,2,6,4,3,2,5,9,3,7};
	  
    mergeSort( arr2, 10);
    for(int i=0;i<10;i++)
		cout<<arr2[i]<<' ';
	cout<<endl;
 
	system("pause");
    return 0;
}

快速排序

在这里插入图片描述

#include <iostream>
#include <algorithm>
#include <ctime>
#include <stdlib.h>


using namespace std;


template <typename T>
int part(T arr[],int l, int r){
    int v=rand()%(r-l+1)+l;
    swap(arr[l], arr[v]);
    int i=l+1;
    int j=r;
    while(i<=j){
    if(arr[i]<arr[l])
         i++;
    else if(arr[j]>arr[l])
         j--;
    else{
    swap(arr[i],arr[j]);
    i++;
    j--;
    }
    }
    swap(arr[j],arr[l]);
    return j;
}
template <typename T>
void _quickSort(T arr[],int l, int r){
	  if( r<=  l ){      
        return;
    }
    int t=part(arr, l, r);
    _quickSort(arr, l, t);
    _quickSort(arr, t+1, r);
}
template<typename T>
void quickSort(T arr[], int n){
       if(n<2) return;
       _quickSort(arr, 0, n-1);
       }


int main() {

    // 测试1 一般性测试
    cout<<"Test for random array, size = "<<10<<", random range [0, "<<10<<"]"<<endl;
    
	int arr2[10] ={1,2,6,4,3,2,5,9,3,7};
	  
    quickSort( arr2, 10);
    for(int i=0;i<10;i++)
		cout<<arr2[i]<<' ';
	cout<<endl;
 
	system("pause");
    return 0;
}

在这里插入图片描述

#include <iostream>
#include <algorithm>
#include <ctime>
#include <stdlib.h>



using namespace std;


template<typename T>
int part3(T arr[],int l, int r){
    
  int v=rand()%(r-l+1)+l;
    swap(arr[l], arr[v]);
    int i=l+1, j=r,cur=l+1;
    while(cur<=j){
    if(arr[cur]<arr[l]){
        swap(arr[cur],arr[i]);
        i++;
        cur++;
    }
   else if(arr[cur]>arr[l]){
        swap(arr[cur],arr[j]);
        j--;
    }else
    cur++;
    }
    swap(arr[i-1],arr[l]);
    return i-1;
}
template<typename T>
void _quickSort(T arr[],int l, int r){
	 if( r<=  l ){      
        return;
    }
    int t=part3(arr, l, r);
    _quickSort(arr, l, t);
    _quickSort(arr, t+1, r);
}
template<typename T>
void quickSort(T arr[], int n){
       if(n<2) return;
       _quickSort(arr, 0, n-1);
       }

int main() {

    // 测试1 一般性测试
    cout<<"Test for random array, size = "<<10<<", random range [0, "<<10<<"]"<<endl;
    
	int arr2[10] ={1,2,6,4,3,2,5,9,3,7};
	  
    quickSort( arr2, 10);
    for(int i=0;i<10;i++)
		cout<<arr2[i]<<' ';
	cout<<endl;
 
	system("pause");
    return 0;
}

堆排序

堆:

  1. 完全二叉树;
  2. 堆中节点的值总是不大于(或不小于)其父节点的值。

堆排序:

  1. 交换堆顶元素和最后一个元素;
  2. 自顶向下重建堆;
  3. 重复步骤1。
  • 升序——最大堆
  • 降序——最小堆

堆排序过程参考博客

#include <iostream>
#include <algorithm>
#include <ctime>
#include <stdlib.h>
#include "SortTestHelper.h"


using namespace std;


template<typename T>
void ajustDown(T arr[], int n,int root){
    int left=2*root+1;
	int right=2*root+2;
	if(left>=n) return;
	int maxIndex;
	if(right<n&&arr[right]>arr[left])
		maxIndex=right;
	else
		maxIndex=left;
	if(arr[root]>arr[maxIndex]) return;
	swap(arr[root],arr[maxIndex]);
	ajustDown(arr,n,maxIndex);
}
template<typename T>
void createHeap(T arr[], int n){
     for(int i=(n-1-1)/2;i>=0;i--){
	 ajustDown(arr,n,i);
	 }
}
template<typename T>
void heapSort(T arr[], int n){
       if(n<2) return;
	   createHeap(arr,n);
      for(int i=0;i<n;i++){
		  swap(arr[0],arr[n-1-i]);
	  ajustDown(arr,n-1-i,0);
	  }
}
int main() {

    // 测试1 一般性测试
    cout<<"Test for random array, size = "<<10<<", random range [0, "<<10<<"]"<<endl;
    
	int arr2[10] ={1,2,6,4,3,2,5,9,3,7};
	  
    heapSort( arr2, 10);
    for(int i=0;i<10;i++)
		cout<<arr2[i]<<' ';
	cout<<endl;
 
	system("pause");
    return 0;
}

排序复杂度分析

排序算法时间复杂度原地排序空间复杂度稳定排序
插入排序O(n²)O(1)
归并排序O(nlogn)O(n)
快速排序O(nlogn)O(1)
堆排序O(nlogn)O(1)

衍生问题

快速排序

力扣215:数组中找到第 k 个最大的元素

class Solution {
public:
    int findKthLargest(vector<int>& nums, int k) {
    int r=nums.size()-1;
    int n;
    n=maxK(nums,0,r,k);
    return n;
    }

private:
    int quikS(vector<int>& nums, int l,int r){
        int rd=rand()%(r-l+1)+l;
        int v=nums[rd];
        swap(nums[l],nums[rd]);
        int l1,r1,cur;
        l1=l+1;
        r1=r;
        cur=l+1;
        while(cur<=r1){
        if(nums[cur]>v)
         swap(nums[l1++],nums[cur++]);
         else if(nums[cur]<v)
         swap(nums[r1--],nums[cur]);
         else cur++;
        }

        swap(nums[l],nums[l1-1]);
        return l1-1;
    }
    int maxK(vector<int>& nums, int l,int r,int k){
    int q;
    q=quikS(nums,l,r);
    if(q+1<k)
   return maxK(nums,q+1,r,k);
    else if(q+1>k)
   return maxK(nums,l,q-1,k);
     else return nums[q];
     return -1;
    }

};

利用归并排序求逆序对

剑指offer51

#include <iostream>
#include <algorithm>
#include <ctime>
#include <stdlib.h>



using namespace std;

//* VS不支持动态长度数组, 即不能使用 T aux[r-l+1]的方式申请aux的空间
    //* 使用VS的同学, 请使用new的方式申请aux空间
    //* 使用new申请空间, 不要忘了在__merge函数的最后, delete掉申请的空间:)
int globalCount=0;
template<typename T>
void merge(T arr[], int l, int mid, int r){
     T *aux=new T[r-l+1];
     for(int i=l; i<r+1; i++)
     aux[i-l]=arr[i];
     int li=l;
     int ri=mid+1;
     for (int j=l; j<r+1; j++){
           if(li>mid) {
           arr[j]=aux[ri-l];
           ri++;
           }
           else if(ri>r){
           arr[j]=aux[li-l];
           li++;
           }
           else if(aux[li-l]>aux[ri-l]){
		   globalCount+=mid-li+1;//在归并排序的基础上加了一句,求逆序对
           arr[j]=aux[ri-l];
           ri++;
           }else{
           arr[j]=aux[li-l];
           li++;
           }
     }
   delete[] aux;  
}
template<typename T>
void _mergeSort(T arr[], int l, int r){
       if(l>=r) return;
       int mid=l+(r-l)/2;
       _mergeSort(arr, l, mid);
       _mergeSort(arr, mid+1, r);
       if(arr[mid]>arr[mid+1])
       merge(arr, l, mid, r);
}
template<typename T>
int mergeSort(T arr[], int n){
       if(n<2) return 0;
       _mergeSort(arr, 0, n-1);
	   return globalCount;
}
int main() {
	int arr2[10] ={7,5,6,4};
	int n=4;
    // 测试1 一般性测试
    cout<<"Test for random array, size = "<<n<<", random range [0, "<<n<<"]"<<endl;
    	
    int c;
   c= mergeSort( arr2, n);
    for(int i=0;i<n;i++)
		cout<<arr2[i]<<' ';
	cout<<endl;
	cout<<"逆序对:"<<c<<endl;
 
	system("pause");
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值