//T(n)为时间复杂度,S(n)为空间复杂度
//直接插入排序,每次都将第i个记录插入到前i-1个有序的记录中
//T(n)=O(n2),S(n)=1,稳定排序
void InsertSort()
{
int j,temp;
for(int i=1;i<n;i++)
{
temp=R[i];
j=i-1;
while(R[j]>temp&&j>=0)
{
R[j+1]=R[j];
j--;
}
R[j+1]=temp;
}
}
/**************************************************************************
希尔排序:间隔交换,每趟不断调整子序列的大小, 从而减少比较次数, 提高时间效率
一个增量是序列 di(i=1,2,…), 其中n>d1> d2 > d2 ….. (通常d1=n/2 di+1=di/2),
每趟将数据表分成di组, 分别对各组进行直接插入排序, 直到最后全部记录在一组为止。
//T(n)=O(nlogn),S(n)=1,不稳定排序
****************************************************************************/
void ShellSort()
{
int d=n/2,j,temp;
while(d>0)
{
for(int i=d;i<n;i++)
{
temp=R[i];
j=i-d;
while(j>=0&&R[j]>temp)
{
R[j+d]=R[j];
j=j-d;
}
R[j+d]=temp;
}
d=d/2;
}
}
/**************************************************************************
起泡排序:在待排序子序列 中,两两比较相邻记录的关键字,若逆序,则交换。
//S(n)=O(n2),S(n)=1,稳定排序
****************************************************************************/
void BubbleSort()
{
int flag=1;
int temp,i=n-1;
while(flag==1)
{
flag=0;
for(int j=0;j<i;j++)
{
if(R[j]>R[j+1])
{
temp=R[j];
R[j]=R[j+1];
R[j+1]=temp;
flag=1;
}
}
i--;
}
}
/**************************************************************************
快速排序:是任取待排序子序列中的一个记录 (例如取第一个) 作为基准,
按照该记录关键字的大小, 将整个子序列划分为左右两个子序列: 。
T(n)=O(nlog2n),不稳定排序
空间性能:排序算法是利用递归实现的,排序过程中需附加栈空间用于存储递归各层信息,
则 S(n)=O(log2n)
****************************************************************************/
int partition(int low,int high)
{
int i=low,j=high;
int temp=R[low];
while(i<j)
{
while(i<j&&R[j]>=temp)
{
j--;
}
R[i]=R[j];
while(i<j&&R[i]<temp)
{
i++;
}
R[j]=R[i];
}
R[i]=temp;
return i;
}
//递归
void QuickSort(int low,int high)
{
if(low<high)
{
int i=partition(low,high);
QuickSort(low,i-1);
QuickSort(i+1,high);
}
}
/**************************************************************************
直接选择排序:在子序列中选择具有最小(或最大)关键字的记录, 若它不是这
子序列中的第一位,则将它调入到第一位上。
时间性能: T(n)=O(n2)
空间性能:需附一个存储单元用于交换,则 S(n)=O(1)
稳定性:不稳定的排序
****************************************************************************/
void SelectSort()
{
int min=0,temp;
for(int i=0;i<n-1;i++)
{
min=i;
for(int j=i+1;j<n;j++)
{
if(R[j]<R[min])
{
min=j;
}
}
if(min!=i)
{
temp=R[i];
R[i]=R[min];
R[min]=temp;
}
}
}
/**************************************************************************
堆排序:堆排序是一种树型选择排序。
基本思想:将待排序的子序列k1, k2, ... ,ki 构造成堆, 从而选择出关键字最大(或最小)记录.
堆排序分为两个步骤:
1、根据初始状态,形成初始堆。
2、通过一系列的记录交换和重新调整
进行排序。
时间性能: T(n)= O(nlog2n)
空间性能:需附一个存储单元用于交换,则 S(n)=O(1)
稳定性:不稳定的排序
****************************************************************************/
void HeapAdjust(int s,int m)
{
int temp=R[s];
for(int j=2*s;j<=m;j*=2)
{
if(j<m&&R[j]<=R[j+1])
{
j++;
}
if(R[j]<temp) break;//如果两个孩子都比父节点小的话,则退出循环
R[s]=R[j];
s=j;
}
R[s]=temp;
}
void HeapSort()
{
int temp;
for(int i=n/2;i>0;i--)
HeapAdjust(i,n);//初始的堆,不断的调整
for(i=n;i>1;i--)
{
temp=R[1];
R[1]=R[i];
R[i]=temp;
HeapAdjust(1,i-1);//重建堆,只要从调整根节点就好了
}
}
/**************************************************************************
归并排序:基本思想:通过对两个有序记录序列的合并来实现排序。
所谓归并是指将若干个已排好序的子序列合并成一个有序的子序列。
这里是将两个有序的子序列合并成一个有序的子序列称二路归并。
时间性能:每一趟归并需将一个数据表的所有记录归并到另一个数据表中,
则一趟归并的时间效率为O(n)。归并排序共需约log2n趟,则总的时间效率为 T(n)=O(nlog2n)
空间性能:需附一个存储单元用于交换,则 S(n)=O(n)
稳定性:稳定的排序
****************************************************************************/
void merge(int low,int mid,int high)
{
int i=low,j=mid+1,k=i;
while(i<=mid&&j<=high&&j<n)
{
if(R[i]<=R[j])
{
R1[k]=R[i];
i++;
k++;
}
else
{
R1[k]=R[j];
j++;
k++;
}
}
while(i<=mid)
{
R1[k]=R[i];
i++;
k++;
}
while(j<=high&&j<n)
{
R1[k]=R[j];
j++;
k++;
}
}
/*每一趟归并排序:两两等长的子序列合并,最后的剩余不完整子序列?
两种情况:
(1)剩余一个子序列
(2)两个不完整序列*/
void MergePass(int length,int n)
{
int i=0;
for(;i+length-1<n;i=i+length*2)
merge(i,i+length-1,i+2*length-1);
if(2*length>=n)
{
merge(i,i+length-1,n-1);
}
//每次排完序之后都将排序之后的结果值赋值到原来的数组中
i=0;
while(i<n)
{
R[i]=R1[i];
i++;
}
}
void MergeSort()
{
int length=1;
while(length<n)
{
MergePass(length,n);
length*=2;
}
}