C++实现各种排序算法类汇总
C++可实现各种排序算法类,比如直接插入排序、折半插入排序、Shell排序、归并排序、简单选择排序、基数排序、对data数组中的元素进行希尔排序、冒泡排序、递归实现、堆排序、用数组实现的基数排序等。
具体代码如下:
#ifndefSORT_H
#defineSORT_H
#include<iostream>
#include<queue>
usingnamespacestd;
//1.直接插入排序
template<classElemType>
voidInsertSort(ElemTypedata[],intn);
//2.折半插入排序
template<classElemType>
voidBInsertSort(ElemTypedata[],intn);
//3.Shell排序
//对data数组中的元素进行希尔排序,n为该数组大小
//increments为增量序列,incrementsLength为增量序列的大小
template<classElemType>
voidShellSort(ElemTypedata[],intincrements[],intn,intincrementsLength);
//1.BubbleSort
template<classElemType>
voidBubbleSort(ElemTypedata[],intn);
//2.快速排序
template<classElemType>
voidQuickSort(ElemTypedata[],intn);
//////////////////
//MergeSort
//////////////////
//归并排序
template<classElemType>
voidMergeSort(ElemTypedata[],intn);
template<classElemType>
voidMergeSortNonRecursion(ElemTypedata[],intn);
//////////////////
//Selectionsort
//////////////////
//简单选择排序
template<classElemType>
voidSelectionSort(ElemTypedata[],intn);
//堆排序
template<classElemType>
voidHeapSort(ElemTypedata[],intn);
///////////////
//RadixSort
///////////////
//静态链表结点
constintDIGITS=10;
constintRADIX=10;
classSLList;
ostream&operator<<(ostream&os,SLList&s);//由于VC++6.0使用usingnamespacestd对于友元不支持
//故在类SLList之前做前向声明
//若使用其他C++编译器,这两句可删去
//静态链表staticlinkedlist
//[0]:头结点
classSLList
{
structNode
{
intkey[DIGITS];
intinfo;
intnext;
};
friendostream&operator<<(ostream&os,SLList&s);
public:
SLList():data(NULL),length(0){};
~SLList();
voidArrange();
voidInit(intarr[],intn);
voidRadixSort();
private:
voidDistribute(int[],int[],int);
voidCollection(int[],int[],int);
Node*data;
intlength;
};
//基数排序
voidRadixSort(intdata[],intn);
//voidRadixSort(SLList&);
///////////////
//util
///////////////
template<classElemType>
voidSwap(ElemType&a,ElemType&b)
{
ElemTypec=a;
a=b;
b=c;
}
intinit(int**data);
template<classElemType>
voidprint(ElemTypedata[],intbegin,intend);
//直接插入排序,数组data用于存放待排序元素,n为待排序元素个数
template<classElemType>
voidInsertSort(ElemTypedata[],intn)
{
ElemTypetmp;
inti,j;
for(i=1;i<n;i++){
if(data[i]>data[i-1])
continue;
tmp=data[i];//保存待插入的元素
data[i]=data[i-1];
for(j=i-1;j>0&&data[j-1]>tmp;j--)
data[j]=data[j-1];//元素后移
data[j]=tmp;//插入到正确位置
}
}
//折半插入排序
template<classElemType>
voidBInsertSort(ElemTypedata[],intn)
{
ElemTypetmp;
inti,j,mid,low,high;
for(i=1;i<n;i++){
tmp=data[i];//保存待插入的元素
low=0;
high=i-1;
while(low<=high){//在data[low..high]中折半查找有序插入的位置
mid=(low+high)/2;//折半
if(tmp<data[mid])
high=--mid;//插入点在低半区
else
low=++mid;//插入点在高半区
}
for(j=i-1;j>=low;j--)
data[j+1]=data[j];//元素后移
data[low]=tmp;//插入到正确位置
}
}
//对data数组中的元素进行希尔排序,n为该数组大小
//increments为增量序列,incrementsLength为增量序列的大小
template<classElemType>
voidShellSort(ElemTypedata[],intincrements[],intn,intincrementsLength)
{
inti,j,k;
ElemTypetmp;
for(k=0;k<incrementsLength;k++){//进行以increments[k]为增量的排序
for(i=increments[k];i<n;i++){
tmp=data[i];
for(j=i;j>=increments[k];j-=increments[k]){
if(tmp>=data[j-increments[k]])
break;
data[j]=data[j-increments[k]];
}
data[j]=tmp;
}
}
}
//冒泡排序
template<classElemType>
voidBubbleSort(ElemTypedata[],intn)
{
intlastSwapIndex=n-1;//用于记录最后一次交换的元素下标
inti,j;
for(i=lastSwapIndex;i>0;i=lastSwapIndex)
{
lastSwapIndex=0;
for(j=0;j<i;j++)
if(data[j]>data[j+1]){
Swap(data[j],data[j+1]);
lastSwapIndex=j;
}
}
}
//快速排序
template<classElemType>
intPartition(ElemTypedata[],intlow,inthigh)
{
ElemTypepivot=data[low];
while(low<high){
while(low<high&&data[high]>=pivot)
high--;
data[low]=data[high];
while(low<high&&pivot>=data[low])
low++;
data[high]=data[low];
}
data[low]=pivot;
returnlow;
}
template<classElemType>
voidQuickSort(ElemTypedata[],intbegin,intend)
{
if(begin>=end)
return;
intpivot=Partition(data,begin,end);
QuickSort(data,begin,pivot-1);
QuickSort(data,pivot+1,end);
}
template<classElemType>
voidQuickSort(ElemTypedata[],intn)
{
if(n<2)
return;
QuickSort(data,0,n-1);
}
//将数组data中,[lptr...rptr-1][rptr...rightEnd]两部分的元素进行合并
//tmpArr为合并时的辅存空间
template<classElemType>
voidMerge(ElemTypedata[],ElemTypetmpArr[],intlptr,intrptr,intrightEnd)
{
intleftEnd=rptr-1;
intptr,i;
ptr=i=lptr;
while(lptr<=leftEnd&&rptr<=rightEnd)
if(data[lptr]<=data[rptr])
tmpArr[ptr++]=data[lptr++];
else
tmpArr[ptr++]=data[rptr++];
while(lptr<=leftEnd)
tmpArr[ptr++]=data[lptr++];
while(rptr<=rightEnd)
tmpArr[ptr++]=data[rptr++];
for(;i<=rightEnd;i++)
data[i]=tmpArr[i];
}
//递归实现
//将数组data中,[begin...end]的元素进行归并排序
template<classElemType>
voidMSort(ElemTypedata[],ElemTypetmpArr[],intbegin,intend)
{
intmiddle;
if(begin>=end)
return;
middle=(begin+end)/2;//将data平分为[begin..middle]和[middle..end]
MSort(data,tmpArr,begin,middle);//递归前半部分
MSort(data,tmpArr,middle+1,end);//递归后半部分
Merge(data,tmpArr,begin,middle+1,end);//将data[begin..middle],data[middle..end]进行归并
}
template<classElemType>
voidMergeSort(ElemTypedata[],intn)
{
ElemType*pArr=NULL;
pArr=newElemType[n];
MSort(data,pArr,0,n-1);
delete[]pArr;
}
//非递归实现
template<classElemType>
voidMPass(ElemTypedata[],ElemTypetmpArr[],intn,intmergeLength)
{
inti=0;
while(i<=n-2*mergeLength){
Merge(data,tmpArr,i,i+mergeLength,i+2*mergeLength-1);
i=i+2*mergeLength;
}
if(i+mergeLength<n)
Merge(data,tmpArr,i,i+mergeLength,n-1);
}
template<classElemType>
voidMergeSortNonRecursion(ElemTypedata[],intn)
{
intmergeLength=1;
ElemType*pArr=NULL;
pArr=newElemType[n];
while(mergeLength<n){
MPass(data,pArr,n,mergeLength);
mergeLength*=2;
}
delete[]pArr;
}
//简单选择排序
template<classElemType>
voidSelectionSort(ElemTypedata[],intn)
{
inti,j,min;
for(i=0;i<n;i++){
min=i;
for(j=i+1;j<n;j++){
if(data[j]<data[min])
min=j;
}
Swap(data[i],data[min]);
}
}
//堆排序
//i为指定元素在数组中的下标
//返回指定结点的左孩子在数组中的下标
inlineintLeftChild(inti)
{
return2*i+1;
}
template<classElemType>
voidHeapAdjust(ElemTypedata[],inti,intn)
{
ElemTypetmp;
intchild;
for(tmp=data[i];LeftChild(i)<n;i=child){
child=LeftChild(i);
if(child!=n-1&&data[child+1]>data[child])//取较大的孩子结点
child++;
if(tmp<data[child])
data[i]=data[child];
else
break;
}
data[i]=tmp;
}
template<classElemType>
voidHeapSort(ElemTypedata[],intn)
{
inti;
for(i=n/2;i>=0;i--)//建堆
HeapAdjust(data,i,n);
for(i=n-1;i>0;i--){//将堆的根结点与最后的一个叶结点交换,并进行调整
Swap(data[0],data[i]);
HeapAdjust(data,0,i);
}
}
//用数组实现的基数排序
voidRadixSort(intdata[],intn)
{
constintradix=10;
constintdigits=10;
inti,j,k,factor;
queue<int>queues[radix];
for(i=0,factor=1;i<digits;i++,factor*=radix){
for(j=0;j<n;j++)
queues[(data[j]/factor)%radix].push(data[j]);//分配
for(k=j=0;j<radix;j++,k++)//收集
while(!queues[j].empty()){
data[k]=queues[j].front();
queues[j].pop();
}
}
}
//分配
voidSLList::Distribute(intfront[],intrear[],intdigit)
{
inti,index;
for(i=0;i<RADIX;i++)
front[i]=0;
for(i=data[0].next;i>0;i=data[i].next){
index=data[i].key[digit];
if(front[index]==0)
front[index]=i;
else
data[rear[index]].next=i;
rear[index]=i;
}
}
//收集
voidSLList::Collection(intfront[],intrear[],intdigit)
{
inti,current;
for(i=0;front[i]==0;i++);//找到第一个非空子表
data[0].next=front[i];//头结点指向第一个非空子表中第一个结点
current=rear[i++];
for(;i<RADIX;i++){
if(front[i]==0)
continue;
data[current].next=front[i];//链接两个非空子表
current=rear[i];
}
data[current].next=0;
}
//用SLList实现的基数排序
voidSLList::RadixSort()
{
inti;
intfront[RADIX],rear[RADIX];
//从最低位优先依次对各关键字进行分配收集
for(i=0;i<DIGITS;i++){
Distribute(front,rear,i);
Collection(front,rear,i);
}
}
SLList::~SLList()
{
delete[]data;
length=0;
}
voidSLList::Init(intarr[],intn)
{
length=n+1;
if(data!=NULL)
delete[]data;
data=newNode[n+1];
data[0].next=1;
for(inti=1;i<=n;i++){
intvalue=data[i].info=arr[i-1];
for(intj=0;j<10;j++){
data[i].key[j]=value%10;//+'0';
value/=10;
}
data[i].next=i+1;
}
data[n].next=0;
}
//根据链表中各结点的指针值调整元素位置,使得SLList中元素按关键字正序排列
voidSLList::Arrange()
{
inti,tmp;
intcurrent=data[0].next;//current存放第一个元素的当前位置
for(i=1;i<length;i++){
while(current<i)//找到第i个元素,并用current存放其在静态链表中当前位置
current=data[current].next;
tmp=data[current].next;
if(current!=i){
Swap(data[current],data[i]);//第i个元素调整到位
data[i].next=current;//指向被移走的元素
}
current=tmp;//为找第i+1个元素做准备
}
}
ostream&operator<<(ostream&os,SLList&s)
{
for(inti=1;i<s.length;i++)
cout<<s.data[i].info<<"";
os<<endl;
returnos;
}
#endif