归并排序---python、Java 对对象的排序方式
1.简介
特点: tim_sort()改进的归并排序()(java 已改为这种方法)
算法特点: 最优 nlogn 最差nlogn 最好 nlogn 空间复杂度O(n:递归底层不是同时占有会释放因此n) 稳定
递归,无限嵌套(方法一直调用)系统一直给方法分配栈帧,把栈空间占完,直到base case。
1.1 原理
将数组进行二分,直到最小单元(1个/2个数据),对最小单元排序并合并往上。
1. 将2个有序数组排序
a【1, 4, 6, 7, 10】 b【2, 3,5 ,8, 9】 c[ 0 , 0 ,0 , 0,0 ,0 ,0 ,0 ,0 ,0]
建立另个一个数组长度为两数组总长, 分别给三个数据一个下标 i ,j ,k
分别比较 a【i】 和b【j】 小的将值赋值给c【k】 ,并将小数组的索引 和 k 加1 ,直到一个数组遍历完,直接将另个数组挪到c剩下空间。
1.2 基本实现
#include<iostream>
#include<ctime>
#include<algorithm>
#include<string.h>
#include<vector>
using namespace std;
class InsertSort{
public:
InsertSort(){};
~InsertSort(){};
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 2000
int main(){
vector<int> arr1(ARR_SIZE);
vector<int> arr2(ARR_SIZE);
vector<int> arr3(ARR_SIZE);
clock_t t;
long sec;
InsertSort Ins;
Ins.GenRandArr(arr1);
// Ins.print(arr1);
memcpy((void*)&arr2[0],(void*)&arr1[0], ARR_SIZE*sizeof(int));
memcpy((void*)&arr3[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);
sec = (clock()-t);
cout<<"shell sort time =" <<sec<<" clock"<<endl;
// Ins.print(arr1);
// Ins.print(arr2);
Ins.compare(arr1,arr2);
}