您的位置:首页 > 编程语言 > Qt开发

常用排序算法

2011-09-08 15:52 246 查看
#pragma once
#ifndef _ALGSORT_H_
#define _ALGSORT_H_
#define M 10                                                                                                       //M的取值范围为5~25最佳;
template <class T>
class AlgSort
{
public:
void BubbleSort(T a[], const int n)                                                              //冒泡排序算法;
{
for(int i=1; i<n; ++i)
for(int j=n-1; j>=i; --j)
if(a[j-1]>a[j])
{
T temp=a[j-1]; a[j-1]=a[j]; a[j]=temp;
}
}
void newBubbleSort(T a[], const int n)                                                       //冒泡的改进排序算法;
{
bool exchange;
for(int i=1; i<n; ++i)
{
exchange=false;
for(int j=n-1; j>=i; --j)
if(a[j-1]>a[j])
{
T temp=a[j-1]; a[j-1]=a[j]; a[j]=temp;
exchange=true;
}
if(exchange==false) return;
}
}
void InsertSort(T a[], const int left, const int right)                                 //直接插入排序算法;
{
T temp; int i, j;
for(i=left+1; i<=right; ++i)
if(a[i]<a[i-1])
{
temp=a[i]; j=i-1;
do
{
a[j+1]=a[j]; j--;
} while(j>=left&&temp<a[j]);
a[j+1]=temp;
}
}
void BinaryInsertSort(T a[], const int left, const int right)                      //折半插入排序算法;
{
T temp; int i, low, high, middle, k;
for(i=left+1; i<=right; ++i)
{
temp=a[i]; low=left; high=i-1;
while(low<=high)
{
middle=(low+high)/2;
if(temp<a[middle]) high=middle-1;
else low=middle+1;
}
for(k=i-1; k>=low; --k) a[k+1]=a[k];
a[low]=temp;
}
}
void ShellSort(T a[], const int left, const int right)                                   //希尔排序算法;
{
int i, j, gap=right-left+1;
T temp;
do
{
gap=gap/3+1;
for(i=left+gap; i<=right; ++i)
if(a[i]<a[i-gap])
{
temp=a[i]; j=i-gap;
do
{
a[j+gap]=a[j];
j-=gap;
} while(j>=left&&temp<a[j]);
a[j+gap]=temp;
}
} while(gap>1);
}
void QuickSort(T a[], const int left, const int right)                                 //快速排序算法;
{
if(left<right)
{
int pivotpos=Partition(a, left, right);
QuickSort(a, left, pivotpos-1);
QuickSort(a, pivotpos+1, right);
}
}
void newQISort(T a[], const int left, const int right)
{
newQuickSort(a, left, right);                                                               //先进行快速排序;
InsertSort(a, left, right);                                                                      //对基本有序的序列进行插入排序;
}
void QuickSort3(T a[], const int left, const int right)                               //三路划分快速排序算法,处理元素序列中的重复值;
{
int i, j, k, p, q;
T pivot=a[right];
if(right<=left) return;
i=left-1; j=right; p=left-1; q=right;
while(1)
{
while(a[++i]<pivot) if(i==j) break;
while(pivot<a[--j]) if(j==i) break;
if(i>=j) break;
T temp=a[i]; a[i]=a[j]; a[j]=temp;
if(a[i]==pivot)
{
p++;
T temp=a[p]; a[p]=a[i]; a[i]=temp;
}
if(pivot==a[j])
{
q--;
T temp=a[q]; a[q]=a[j]; a[j]=temp;
}
}
T temp=a[i]; a[i]=a[right]; a[right]=temp;
j--; i++;
for(k=right-1; k>=q; k--, i++)
{
T temp=a[k]; a[k]=a[i]; a[i]=temp;
}
for(k=left; k<=p; k++, j--)
{
T temp=a[k]; a[k]=a[j]; a[j]=temp;
}
QuickSort3(a, left, j);
QuickSort3(a, i, right);
}
void SelectSort(T a[], const int left, const int right)                                //直接选择排序算法;
{
for(int i=left; i<right; i++)
{
int k=i;                                                                                                      //在a[i]到a[n-1]寻找最小排序码的元素;
for(int j=i+1; j<=right; j++)
if(a[j]<a[k]) k=j;
if(k!=i)
{
T temp=a[i]; a[i]=a[k]; a[k]=temp;
}
}
}
void MergeSort(T a[], T aa[], const int left, const int right)                    //两路归并排序算法;
{
if(left>=right) return;
int mid=(left+right)/2;                                                                               //从中间划分为两个子序列;
mergeSort(a, aa, left, mid);
mergeSort(a, aa, mid+1, right);
merge(a, aa, left, mid, right);                                                                    //合并;
}
void newMergeSort(T a[], T aa[], const int left, const int right)            //改进的两路归并排序算法;
{
doSort(a, aa, left, right);
InsertSort(a, left, right);
}
private:
int Partition(T a[], const int low, const int high)
{
int pivotpos=low;
T pivot=a[low];
for(int i=low+1; i<=high; ++i)
if(a[i]<pivot)
{
pivotpos++;
if(pivotpos!=i)
{
T temp=a[pivotpos]; a[pivotpos]=a[i]; a[i]=temp;
}
}
a[low]=a[pivotpos]; a[pivotpos]=pivot;
return pivotpos;
}
private:
void newQuickSort(T a[], const int left, const int right)                   //取中间元素的快速排序算法;
{
if(right-left<=M) return;
int pivotpos=newPartition(a, left, right);
newQuickSort(a, left, pivotpos-1);
newQuickSort(a, pivotpos+1, right);
}
int newPartition(T a[], const int left, const int right)
{
int i=left, j=right-1;
if(left<right)
{
T pivot=median3(a, left, right);
for(; ;)
{
while(i<j&&a[i]<pivot) i++;
while(i<j&&pivot<a[j]) j--;
if(i<j)
{
T temp=a[i]; a[i]=a[j]; a[j]=temp;
i++; j--;
}
else break;
}
if(a[i]>pivot)
{
a[right]=a[i]; a[i]=pivot;
}
}
return i;
}
T& median3(T a[], const int left, const int right)                                 //三者取中算法;
{
int mid=(left+right)/2; int k=left;
if(a[mid]<a[k]) k=mid;
if(a[right]<a[k]) k=right;
if(k!=left)
{
T temp=a[left]; a[left]=a[k]; a[k]=temp;                                             //最小者交换到left位置;
}
if(mid!=right&&a[mid]<a[right])
{
T temp=a[mid]; a[mid]=a[right]; a[right]=temp;                             //中间值交换到right位置;
}
return a[right];
}
private:
void merge(T a[], T aa[], const int left, const int mid, const int right)  //两路归并排序算法;
{
for(int k=left; k<=right; k++)
aa[k]=a[k];
int s1=left, s2=mid+1, t=left;
while(s1<=mid&&s2<=right)
{
if(aa[s1]<=aa[s2]) a[t++]=aa[s1++];
else a[t++]=aa[s2++];
}
while(s1<=mid) a[t++]=aa[s1++];
while(s2<=right) a[t++]=aa[s2++];
}
private:
void doSort(T a[], T aa[], const int left, const int right)
{
if(left>=right) return;
if(right-left+1<M) return;
int mid=(left+right)/2;
doSort(a, aa, left, mid);
doSort(a, aa, mid+1, right);
improvedMerge(a, aa, left, mid, right);
}
void improvedMerge(T a[], T aa[], const int left, const int mid, const int right)
{
int s1=left, s2=right, t=left, k;
for(k=left; k<=mid; k++)
aa[k]=a[k];
for(k=mid+1; k<=right; k++)
aa[right+mid+1-k]=a[k];
while(t<=right)
{
if(aa[s1]<=aa[s2]) a[t++]=aa[s1++];
else a[t++]=aa[s2--];
}
}
};
#endif
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息