这个是我女朋友整理的排序算法,恩,她去了哪?MARVELL
程序依然是简单易懂,并且整理得当
#include <iostream>
using namespace std;
#define NUM 5
/**************************************************************
* 堆的定义 n 个元素的序列 {k1,k2,...,kn}当且仅当满足下列关系时,
* 称为堆:
* ki<=k2i ki<=k2i+1 (i=1,2,...,n/2)
* 或
* ki>=k2i ki>=k2i+1 (i=1,2,...,n/2)
* 堆排序思路:
* 建立在树形选择排序基础上;
* 将待排序列建成堆(初始堆生成)后,序列的第一个元素(堆顶元素)就一定是序列中的最大元素;
* 将其与序列的最后一个元素交换,将序列长度减一;
* 再将序列建成堆(堆调整)后,堆顶元素仍是序列中的最大元素,再次将其与序列最后一个元素交换并缩短序列长度;
* 反复此过程,直至序列长度为一,所得序列即为排序后结果。
**************************************************************/
template<typename T>
void HeapAdjust(T a[],int s,int n) /* 排列成堆的形式 */
{
int i;
T temp = a[s-1];
for(i=s*2; i<=n; i*=2)
{
if(i<n && a[i-1]<a[i])//取较大孩子结点
i++;
if(temp>a[i-1])//如果父结点大于子结点,跳出循环
break;
a[s-1] = a[i-1]; /* “父节点”比“较大的孩子节点”大则互换 ,保证父节点比所有子节点都大(父节点存储在前面)*/
s = i;//父节点移到被交换的子结点,递归向下检查
}
a[s-1] = temp;
}
template<typename T>
void HeapSort(T a[],int n) /* 堆排序函数 */
{
int i;
T temp;
for(i=n/2; i>0; i--)//因为当前树不是堆,无序,所以从n/2处(n/2向后的结点的子树可以看作堆),开始调整为堆。
{
HeapAdjust(a, i, n);/* 处理后,a[i]是这个数组后半部分的最大值 */
}
for(i=n; i>1; i--)//排到前面的元素只剩一个就结束了
{
temp = a[0]; /* 把根元素(剩下元素中最大的那个)放到结尾 ,下一次只要排剩下的数就可以啦*/
a[0] = a[i-1];
a[i-1] = temp;
HeapAdjust(a, 1, i-1);
}
}
/*冒泡排序*/
template<typename T>
void BubbleSort(T a[],int n)
{
T temp;
int i,j;
int flag = 0;
for(i=1; i<n; i++)
{
flag = 0;
for(j=0; j<n-i; j++)
{
if(a[j]>a[j+1])
{
a[j] = a[j]^a[j+1];
a[j+1] = a[j]^a[j+1];
a[j] = a[j]^a[j+1];
flag = 1;
}
}
if(flag==0)
break;
}
}
//希尔排序
template<typename T>
void ShellSort(T a[],int n)
{
int gap;
int i,j,k;
T temp;
for(gap=n/2; gap>0; gap/=2)
{
for(i=gap; i<n; i+=gap)
{
temp = a[i];
k = i;
while((k>0) && (temp<a[k-gap]))
//while(temp<a[k-gap])
{
a[k] = a[k-gap];
k -= gap;
}
a[k] = temp;
}
}
}
/*快速排序*/
template<typename T>
void QuickSort(T a[], int low, int high)
{
T pivot;
int i,j;
if(low<high)
{
i = low;
j = high;
pivot = a[low];
while(i<j)
{
while((i<j)&&(pivot<=a[j]))
j--;
if(i<j)
a[i++] = a[j];
while((i<j)&&(a[i]<=pivot))
i++;
if(i<j)
a[j--] = a[i];
}
a[i] = pivot;
QuickSort(a,low,i-1);
QuickSort(a,i+1,high);
}
}
/*选择排序 不稳定*/
template<typename T>
void SelectSort1(T a[],int n)
{
int i,j;
for(i=0; i<n-1; i++)
{
for(j=i+1; j<n; j++)
{
if(a[j]<a[i])
{
a[i] = a[i]^a[j];
a[j] = a[i]^a[j];
a[i] = a[i]^a[j];
}
}
}
}
template<typename T>
void SelectSort(T a[],int n)
{
int i,j,min;
T temp;
for(i=0; i<n-1; i++)
{
min = i;
for(j=i+1; j<n; j++)
{
if(a[j]<a[min])
{
min = j;
}
}
temp = a[i];
a[i] = a[min];
a[min] = temp;
}
}
/*简单插入排序*/
template<typename T>
void InsertSort(T a[],int n)
{
T temp;
int i,j;
for(i=1; i<n; i++)
{
temp = a[i];
for(j=i; j>0 &&(temp<a[j-1]); j--)
{
a[j] = a[j-1];
}
a[j] = temp;//注意是a[j]
}
}
/*折半插入:用low和high标定查找界限,下一次的查找
范围是上一次的一半*/
template<typename T>
void BiInsert_sort(T a[],int n)
{
int low,mid,high;
int i,j;
T temp;
for(i=1; i<n; i++)
{
low = 0;
high = i-1;
temp = a[i];
while(low<=high)
{
mid = (low+high)/2;
if(temp<=a[mid])
high = mid-1;
else
low = mid+1;
}
for(j=i; j>mid; j--)
a[j] = a[j-1];
a[low] = temp;或者是high+1,不能是m
}
}
/*2-路插入排序是在折半插入排序的基础上再改进之,
其目的是减少排序过程中移动记录的次数,但为此需
要n个记录的辅助空间。时间复杂度为O(n^2)。
理解:所谓的2-路,是指优先插入在序列前面或后面,
然后再考虑插入到中间。*/
template<typename T>
void TwoInsert_sort(T a[],T t[],int n)
{
int i;
int first=0, final=0;
t[0] = a[0];
for(i=1; i<n; i++)
{
if(a[i]<=t[first])
{
first = (first-1+n)%n;
t[first] = a[i];
}
else if(a[i]>=t[final])
{
final = final+1;
t[final] = a[i];
}
else
{
int j = final++;
while(a[i]<t[j])
{
t[(j+1+n)%n] = t[(j+n)%n];//
j = (j-1+n)%n;//
}
t[j+1] = a[i];//j+1
}
}
for(i=0; i<n; i++)
a[i] = t[(first+i)%n];
}
int main()
{
int a[NUM];
int b[NUM];
int i;
char s;
B: cout<<"Please input "<<NUM<<" integers:\n";
for(i=0; i<NUM; i++)
{
cin>>a[i];
}
cout<<"排序算法:\n";
cout<<"1: BubbleSort...\n";
cout<<"2: InsertSort...\n";
cout<<"3: BiInsert_sort...\n";
cout<<"4: TwoInsert_sort...\n";
cout<<"5: SelectSort...\n";
cout<<"6: SelectSort1...\n";
cout<<"7: QuickSort...\n";
cout<<"8: ShellSort...\n";
cout<<"9: HeapSort...\n";
cout<<"0: 重新输入数组数据...\n";
while(1)
{
A: cout<<"请选择排序算法,输入编号:\n";
cin>>s;
switch(s)
{
case '1':
BubbleSort(a,NUM);
break;
case '2':
InsertSort(a,NUM);
break;
case '3':
BiInsert_sort(a,NUM);
break;
case '4':
TwoInsert_sort(a,b,NUM);
break;
case '5':
SelectSort(a,NUM);
break;
case '6':
SelectSort1(a,NUM);
break;
case '7':
QuickSort(a,0,NUM-1);
break;
case '8':
ShellSort(a,NUM);
break;
case '9':
HeapSort(a,NUM);
break;
case '0':
goto B;
//break;
default:
//cout<<"选择无效!\n";
cout<<"选择无效,请重新选择!\n";
goto A;
}
cout<<"The result is:\n";
for(i=0; i<NUM; i++)
{
cout<<a[i]<<" ";
}
cout<<endl;
}
return 0;
}