排序算法

//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;

       }

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值