快速排序
1. 原理
单轴快排
改进->
双轴快排:Java: arry.sort(int) 经典
算法性能:平均 O(nlogn ), 最差 (每次选的边界为最大值,每次只能分出一个值, 可优化:随机取值,判断是不是顺序增长/减小)O(n^2) 最小:(nlogn )
1.2 基本实现:
#include<iostream>
#include<ctime>
#include<algorithm>
#include<string.h>
#include<vector>
using namespace std;
class InsertSort{
public:
InsertSort(){};
~InsertSort(){};
int QuickSort(vector<int>&arr , int left, int rightbound){ //效率低,待分析
if(left>=rightbound) return 0;
int mid = partition(arr, left, rightbound);
QuickSort(arr, left, mid-1);//边界不应参加后续排序
QuickSort(arr, mid+1, rightbound);
// print(arr);
return 0;
};
int partition1(vector<int>&arr , int leftbound , int rightbound){
int left =leftbound;
int right =rightbound-1;
int pivot =arr[rightbound];
while(left<=right){
while((arr[left]<=pivot)&&(left<=right)){left++;}
while((arr[right]>pivot)&&(right>=left)){right--;}
// cout<<arr[left]<<" inline " <<arr[right] <<endl;
swap(arr[left],arr[right]);
// print(arr);
}
// cout<<arr[left]<<" " <<pivot <<endl;
if(left<right)
swap(arr[left],arr[rightbound]);
// print(arr);
return left;
}
int partition(vector<int>&arr , int leftbound , int rightbound){ //效率高,待分析
int left =leftbound;
int right =rightbound-1;
int pivot =arr[rightbound];
while(1){
while((arr[left]<pivot)&&(left<=right)){left++;}
while((arr[right]>pivot)&&(right>=left)){right--;}
if(left<right){
// cout<<arr[left]<<" inline " <<arr[right] <<endl;
swap(arr[left],arr[right]);
// print(arr);
left++;
right--;
}else{
// cout<<"out left= "<<left<<" right="<< right<<endl;
break;
}
}
// cout<<arr[left]<<" " <<pivot <<endl;
swap(arr[left],arr[rightbound]);
// print(arr);
return left;
}
int sort(vector<int>&arr){
//gap =1 is InsertSort
int gap = 1;//arr.size()>>1;
for(; gap>0; gap=gap>>1){
for(int i=gap; i<arr.size(); i++){
for(int j=i; j>gap-1; j-=gap){
if(arr[j]<arr[j-gap]){
swap(arr[j],arr[j-gap]);
}else{
break;
}
}
}
}
return 0;
};
int MergeSort(vector<int>& arr, int left ,int right){
if(left == right) return 0;
int mid =(right-left)/2 + left; //括号内不能补+1 否则一直除不尽
// cout<<"left ="<<left<<" right="<<right<<" mid1="<<mid<<endl;
MergeSort(arr, left , mid); //left sort
MergeSort(arr, mid+1 , right); //right sort
merge(arr, left , mid , right); //merge
}
void merge(vector<int> &arr, int left , int mid1 ,int right){
// cout<<"left ="<<left<<" right="<<right<<" mid1="<<mid1<<endl;
int mid = mid1;
int i =left;
int j =mid+1;
int k =0;
vector<int> temp(right-left+1);
while((i<=mid)&&(j<=right)){
temp[k++] = arr[i]<=arr[j]? arr[i++]:arr[j++];
// cout<<"k-1 " << k-1<<" "<<temp[k-1]<<endl;
}
while(i<=mid){ temp[k++]= arr[i++];}
while(j<=right){ temp[k++]= arr[j++];}
// print(temp);
// print(arr);
for(i=0; i<temp.size(); ++i){ //temp.size()小心越界
arr[i+left]=temp[i];///left
}
// print(arr);
}
int K_sort(vector<int>&arr){
//gap =1 is InsertSort
int h=1 ;
while(h<arr.size()/3){ h = 3*h+1;}
int gap = h;
// cout<< gap<<endl;
for(; gap>0; gap=(gap-1)/3){
for(int i=gap; i<arr.size(); i++){
for(int j=i; j>gap-1; j-=gap){
if(arr[j]<arr[j-gap]){
swap(arr[j],arr[j-gap]);
}else{
break;
}
}
}
}
return 0;
};
void mov(vector<int> &arr,int index ,int end){
int tmp = arr[end];
for(int i=end; i>index; --i){
arr[i]=arr[i-1];
}
arr[index]= tmp;
}
void GenRandArr(vector<int> &arr)
{
srand(time(0));
for(int i=0; i<arr.size(); ++i){
arr[i]=rand()%10;
}
};
void print(const vector<int> &arr)
{
for(int i=0; i<arr.size(); ++i){
cout<< arr[i]<<" ";
}
cout<<endl;
}
void compare(vector<int>& arr1, vector<int>&arr2)
{
for(int i=0; i<arr1.size(); ++i)
{
if(arr1[i]!=arr2[i]){
cout<<"compare wrong" <<endl;
return;
}
}
cout<<"compare right"<<endl;
};
private:
void swap(int &a ,int&b){
int tmp =a;
a =b;
b= tmp;
};
};
bool cmp(const int &a ,const int &b){
return (a<b);
}
#define ARR_SIZE 10000
int main(){
vector<int> arr1(ARR_SIZE);
// int arr[]={7,3,2,8,1,9,5,4,6,10,6};
vector<int> arr2(ARR_SIZE);
vector<int> arr3(ARR_SIZE);
clock_t t;
long sec;
InsertSort Ins;
Ins.GenRandArr(arr1);
// memcpy((void*)&arr1[0],(void*)&arr[0], ARR_SIZE*sizeof(int));
// Ins.print(arr1);
memcpy((void*)&arr3[0],(void*)&arr1[0], ARR_SIZE*sizeof(int));
memcpy((void*)&arr2[0],(void*)&arr1[0], ARR_SIZE*sizeof(int));
//Ins.print(arr2);
t =clock();
Ins.K_sort(arr3);
sec = (clock()-t);
cout<<"shell Ksort time =" <<sec<<" clock"<<endl;
t =clock();
sort(arr2.begin(), arr2.end() ,cmp);
sec = (clock()-t);
cout<<"SortLib time ="<< sec<<" clock"<<endl;
t =clock();
// Ins.sort(arr1);
// Ins.MergeSort( arr1, 0 ,arr1.size()-1);
Ins.QuickSort(arr1, 0, arr1.size()-1);
sec = (clock()-t);
cout<<"shell sort time =" <<sec<<" clock"<<endl;
// Ins.print(arr1);
// Ins.print(arr2);
Ins.compare(arr1,arr2);
}