33,008
社区成员
发帖
与我相关
我的任务
分享
//quick sort
int partition(int* arr,const int left,const int right){
int leIdx=left-1;
for(int i=left;i<=right-1;++i){
if(arr[i]<=arr[right]){
++leIdx;
swap(arr[leIdx],arr[i]);
}
}
swap(arr[leIdx+1],arr[right]);
return leIdx+1;
}
void quickSort(int* arr,const int left,const int right){
if(left<right){
int index=partition(arr,left,right);
quickSort(arr,left,index-1);
quickSort(arr,index+1,right);
}
}
void quickSort(int* arr,const int len){
quickSort(arr,0,len-1);
}
//heap sort
void heapDown(int* arr,const int idx,const int len){
if(idx>=static_cast<int>(len/2)){//该节点是叶子
return;
}
int maxSon=2*idx+1;//初始最大儿子是左儿子
if( maxSon+1<len && arr[maxSon+1]>arr[maxSon]){//如果右儿子存在,并且大于左儿子
++maxSon;
}
if(arr[maxSon]>arr[idx]){
swap(arr[maxSon],arr[idx]);
heapDown(arr,maxSon,len);
}
}
void buildHeap(int* arr,const int len){
for(int i=static_cast<int>(len/2)-1;i>=0;--i){
heapDown(arr,i,len);
}
}
void heapSort(int* arr,const int len){
buildHeap(arr,len);
for(int i=len-1;i>=1;--i){
swap(arr[0],arr[i]);
heapDown(arr,0,i);
}
}
//main 函数
#include "sort.h"
#include <iostream>
#include <string>
#include <ctime>
using namespace std;
int* generateRandom(int len,const int low,const int high){
::srand(time(NULL));
int* arr=new int[len];
for(int i=0;i<len;++i){
arr[i] = low+rand()%(high-low+1);
}
return arr;
}
void testSortFunction(const int* unsorted,int len,SortFunction sf,const string name){
int* arr=new int[len];
for(int i=0;i<len;++i){
arr[i]=unsorted[i];
}
clock_t start=clock();
sf(arr,len);//sort
clock_t end=clock();
cout<<name<<" Count "<<len<<" costs "<<(end-start)/(double)CLOCKS_PER_SEC<<" s"<<endl;
delete [] arr;
}
void main(int argc,char* argv[]){
const int N = 10000000;
int* unsorted = generateRandom(N,0,2000);
cout<<"Random Count: "<<N<<endl;
cout<<"******************************************************"<<endl;
testSortFunction(unsorted,N,quickSort,"Quick Sort");
testSortFunction(unsorted,N,heapSort,"Heap Sort");
cout<<"******************************************************"<<endl;
delete [] unsorted;
system("pause");
}
// 123.cpp : 定义控制台应用程序的入口点。
//堆排序就没什么用了,这个版本的堆排序太慢了
#include "stdafx.h"
#include <iostream>
#include <vector>
#include <windows.h>
#include <ctime>
#include <algorithm>
using namespace std;
//typedef std::vector<int>& VT;
typedef int* VT;
//递归调用次数太多 栈溢出!
void quick_sort_rec(int *a,int low,int high);
//非递归版 --迭代
void quick_sort(int *base,int start,int end);
//int _t;
inline void _swap_kn(int & a,int & b){
int _t;
_t = a;
a = b;
b = _t;
}
inline void _insert_sort_kn(VT v,unsigned int org_beg,unsigned int org_nd){//插入排序
if(org_nd <= org_beg)
return ;
int *p;
p = new int[org_nd - org_beg];
//p[0] = v[org_beg];
for(unsigned int x = 0;x < org_nd - org_beg;++x){
p[x] = v[org_beg + x];
for(unsigned int i = x;i;--i)
if(p[i] < p[i - 1])
_swap_kn(p[i],p[i-1]);
}
for(unsigned int x = 0;x < org_nd - org_beg;++x)
v[org_beg + x] = p[x];
delete [] p;
}
inline void _selet_sort_kn(VT v,unsigned int org_beg,unsigned int org_nd){//选择排序
for(unsigned int beg = org_beg,nd = org_nd;;++ beg,-- nd){
if(nd <= beg + 1 ){//数据长度不大于1 ,则返回
break;
}
if(nd - beg == 2){
if(v[nd - 1] < v[beg])
_swap_kn(v[beg],v[nd - 1]);
break;
}
if(nd - beg == 3){
if(v[beg + 1] < v[beg])//前面两个排序
_swap_kn(v[beg],v[beg + 1]);
if(v[beg + 2] < v[beg + 1])//前后两个排序/确定 v[beg + 2] 最大
_swap_kn(v[beg +1],v[beg + 2]);
if(v[beg + 1] < v[beg])//确定剩下两个
_swap_kn(v[beg],v[beg + 1]);
break ;
}
//beg,beg + 1,nd -2,nd -1 四个数中取极大极小值//beg,beg + x ,nd - 1 - x,nd -1
if(v[nd - 1] < v[beg])
_swap_kn(v[beg],v[nd - 1]);
for(unsigned int x =1;;++x){
if(beg + x < nd - 1 - x){
//cout<<v[beg]<<" "<<v[beg + x]<<" "<<v[nd - 1 - x]<<" "<<v[nd -1]<<endl;
if(v[nd - 1 - x] < v[beg + x])
_swap_kn(v[beg + x],v[nd - 1 - x]);
if(v[beg + x] < v[beg])
_swap_kn(v[beg],v[beg + x]);
if(v[nd - 1] < v[nd -1 - x])
_swap_kn(v[nd - 1 - x],v[nd - 1]);
//cout<<v[beg]<<" "<<v[beg + x]<<" "<<v[nd - 1 - x]<<" "<<v[nd -1]<<endl;
//cout<<endl;
}
else {
if(beg + x == nd - 1 - x){
//cout<<v[beg]<<" "<<v[nd - 1 - x]<<" "<<v[nd -1]<<endl;
if(v[beg + x] < v[beg])
_swap_kn(v[beg],v[beg + x]);
if(v[nd - 1] < v[nd - 1 - x])
_swap_kn(v[nd - 1 - x],v[nd -1]);
if(v[beg + x] < v[beg])
_swap_kn(v[beg],v[beg + x]);
//cout<<v[beg]<<" "<<v[nd - 1 - x]<<" "<<v[nd -1]<<endl;
}
break;
}
}
}
}
inline void _sort_kn(VT v,unsigned int org_beg,unsigned int org_nd){
if(org_nd <= org_beg)
return;
//无效数据,直接返回
if(org_nd - org_beg <= 32){
//insert_sort_kn(v,org_beg,org_nd);
_selet_sort_kn(v,org_beg,org_nd);
return ;
}
//
/*
if(org_nd - org_beg == 1)
return ;
if(org_nd - org_beg == 2){
if(v[org_beg + 1] < v[org_beg])
_swap_kn(v[org_beg +1],v[org_beg]);
return ;
}
if(org_nd - org_beg == 3){
if(v[org_beg + 1] < v[org_beg])
_swap_kn(v[org_beg + 1],v[org_beg ]);
if(v[org_beg + 2] < v[org_beg])
_swap_kn(v[org_beg + 2],v[org_beg]);
if(v[org_beg + 2] < v[org_beg + 1])
_swap_kn(v[org_beg + 2],v[org_beg + 1]);
return ;
}
*/
int iVal = v[rand()%(org_nd - org_beg) + org_beg];
unsigned int min_top,max_beg;
//min_top = 0;
for(unsigned int x = org_beg,y = org_nd;;){
while(x < y)//x 不可能大于org_nd,不需要这个边界
if(v[x] < iVal) ++x;
else
break;
//这里返回相等,说明x左边的数都是小于iVal的
while(x < y)//y - 1 不可能小于org_beg,不需要这个边界,y - 1 == x 是有可能的的.
if(!(v[y -1] < iVal)) -- y;
else
break;
//这里返回相等,则说明剩余的数都不小于iVal的,这时末端迭代器y - 1之后的应该都是不小于iVal的
//y - 1指向的应该是x的前一个,即 y-1 == x - 1即x== y
//即当x == y时, x 是min的末端迭代器,y - 1是不小于的末端迭代器,即y是指向最开始一个不小于iVal的数
if(x == y){//如果是由于在剩余范围内没有了不小于iVal的数据,即确定min_top边界为此时的x
min_top = x;
break;
}
// x y-1 不可能取等值,一个数步可能同时小于又不小于一个数.
// if(x < y - 1 && 1 < y){//1<y 即 y - 1 > 0 ,保证y - 1 是有效值 ,x < y - 1 即不小于值在左边,不小于值在右边,该数据有效
//前面已经保证了迭代器指向是必然有效的,因此 条件判断取消
_swap_kn(v[x],v[y-1]);
}
//max_beg = org_nd;
for(unsigned int x = min_top,y = org_nd;x != org_nd;){
while(x < y)
if(v[x] == iVal) ++ x;//查找最开始一个不等于iVal的数.
else
break;
//(x == y)说明剩余的都是相等
//x返回的是第一个不相等的数,如果后面没有了数据,则返回末端迭代器
while (x < y)
if(v[y -1] != iVal) -- y;//查找最后一个等于iVal的数
else
break;
if(x == y){//如果返回相等的末端迭代器,则确定max_beg边界.
max_beg = x;
break;
}
_swap_kn(v[x],v[y-1]);
}
_sort_kn(v,org_beg,min_top);
_sort_kn(v,max_beg,org_nd);
}
void sort_kn(VT v,unsigned int n){
_sort_kn(v,0,n);
}
class HEAP{
vector<int> v;
public:
HEAP(){v.resize(1);};
HEAP(const HEAP& source){v = source.v;};
HEAP(int n){v.resize(2);v[1] = n;};
void push_back(int );
int pop_back();
unsigned int size(){return v.size() - 1;};
~HEAP(){};
};
void HEAP::push_back(int val){
unsigned int n = v.size();
v.push_back(val);
;//有效数据起始的编号为1,0为无效标号,目的是为了表达式简便.
while(n > 1){
if(v[n] < v[n/2]){
_swap_kn(v[n],v[n/2]);
n /= 2;
}
else
break;
}
};
int HEAP::pop_back(){
if( !size())
return -1;//实际应该返回异常.
v[0] = v[1];
v[1] = *(v.rbegin());
if(size() == 1){
v.pop_back();
return v[0];
}
v.pop_back();
unsigned int n = 1;
for(;n < v.size();){ //v.size() == size() + 1//含义是编号起始为1开始的.
unsigned int x = n + n + 1;
if( x < v.size()){//还是满二叉树,应该原则上应该是 x <= size();
if(v[x - 1] < v[x])
-- x;//如果左子树最小,则选取左子树 x = n + n,否则选择右子树,x = n + n + 1;
if(v[x] < v[n]){
_swap_kn(v[n],v[x]);//如果根比子树还大,
n = x;
continue;
}
else
break;
}
else{//不是满二叉树,则只需要判断比较 可能还有的左叉树即可.返回
x = n + n;
if(x < v.size()){//左叉树还在.
if(v[x] < v[n])
_swap_kn(v[n],v[x]);
}
//已经没有给n赋值的必要了
//左叉树也没有.
break;
}
}
return v[0];;
};
void heap_sort(VT v,unsigned int n){
HEAP cHeap;
for(unsigned int x = 0;x < n;++x)
cHeap.push_back(v[x]);
for(unsigned int x = 0;x < n;++x)
v[x] = cHeap.pop_back();
}
int _tmain(int argc, _TCHAR* argv[])
{
Sleep(10);
srand((unsigned int) time(NULL));
const unsigned int n = 10000000;
//cin >>n;
vector<int> a;
a.resize(n);
int *b = new int[n];
int *c = new int[n];
int *d = new int[n];
for(unsigned int x = 0;x < n;++x)
a[x] = rand();
for(unsigned int x = 0;x < n;++x){
b[x] = a[x];
c[x] = a[x];
d[x] = a[x];
}
time_t t;
//for(unsigned int x = 0;x < n;++x)
// cout<<a[x]<<" ";
//cout<<endl;
for(unsigned int x = 0;x < n; ++x){
if(b[x] != d[x]){
cout<<"原始数据部正确"<<endl;
break;
}
}
t = clock();
//for(unsigned int x = 0;x < 100;++x)
sort(b,b + n );
//sort(b.begin(),b.end());
cout<<"STL sort花费时间"<<clock() - t<<endl;
//cout<<"STL sort"<<endl;
//for(unsigned int x = 0;x < n;++x)
// cout<<b[x]<<" ";
//cout<<endl;
t = clock();
//for(unsigned int x = 0;x < 100;++x)
//sort(b,b+n);
sort_kn(c,n);
cout<<"sort_kn花费时间"<<clock() - t<<endl;
// for(unsigned int x = 0;x < n;++x)
// cout<<a[x]<<" ";
// cout<<endl;
t = clock();
heap_sort(d,n);
cout<<"heap_sort花费时间"<<clock() - t<<endl;
// for(unsigned int x = 0;x < n;++x)
// cout<<a[x]<<" ";
// cout<<endl;
for(unsigned int x = 0;x < n;++x)
if(b[x] !=d[x]){
cout<<"算法不正确"<<endl;
cout<<"STL sort"<<endl;
for(unsigned int x = 0;x < n;++x)
cout<<b[x]<<" ";
cout<<endl;
cout<<"测试程序"<<endl;
for(unsigned int x = 0;x < n;++x)
cout<<d[x]<<" ";
cout<<endl;
break;
}
delete [] b;
delete [] c;
delete [] d;
return 0;
}
typedef void (*SortFunction)(int*, int);
void map_sort(VT v,unsigned int n){
map<int,int> vDest;
vDest.clear();
for(unsigned int x = 0;x < n;++x)
vDest[v[x]] ++;
unsigned int i = 0;
for(map<int,int>::iterator p = vDest.begin();p != vDest.end();++ p){
int temp = p->first;
for(int x = 0;x < p->second;++ x)
v[i++] = temp;
}
}
偷偷懒,调用一下现成的,
估计比楼主的堆排序要快.
如果不用模板的话.估计还要快.