16排序算法的实现和比较

实验目的:

⑴ 熟悉各种内部排序算法

⑵ 掌握常用排序算法的实现方法

实验内容:

1、采用书上第 264 页定义的记录顺序存储表示,编程实现下列排序算法,并比较算法的优缺点。

1)直接插入排序 2)快速排序 3)简单选择排序 4)堆排序

程序清单:

#include<stdio.h>

#include<stdlib.h>

#define TRUE 1

#define ERROR 0

#define FALSE 0

#define OK 1

#define MAXSIZE 20

#define LT(a,b) (a<b)

#define EQ(a,b) (a==b)

typedef int Status;

typedef int KeyType;

typedef int InfoType;

typedef struct

{

       KeyType key;

       InfoType otherinfo;

}RedType;

typedef struct

{

       RedType r[MAXSIZE+1];

       int length;

}SqList;

typedef SqList HeapType;

Status InitList(SqList &L)

{

       L.length=0;

       return OK;

}

Status CreateList(SqList &L,int n)

{

       int i;

       printf("输入%d个元素:\n",n);

       for(i=1;i<=n;i++)

       {

              scanf("%d",&L.r[i].key);

              L.length++;

       }

       if(L.length==0) return ERROR;

       return OK;

}

Status DispList(SqList &L)

{

       int i;

       if(L.length==0) return ERROR;

       for(i=1;i<=L.length;i++)

       {

              printf("%d ",L.r[i].key);

       }

       printf("\n");

       return OK;

}

//直接插入排序

void InsertSort(SqList &L)

{

       int i,j;

       for(i=2;i<=L.length;i++)

       {

              if(LT(L.r[i].key,L.r[i-1].key))

              {

                     L.r[0]=L.r[i];

                     for(j=i-1;LT(L.r[0].key,L.r[j].key);j--)

                     {

                            L.r[j+1]=L.r[j];

                     }

                     L.r[j+1]=L.r[0];

              }

       }

}

//快速排序

Status Partition(SqList &L,int low,int high)

{

       int pivotkey;

       L.r[0]=L.r[low];

       pivotkey=L.r[low].key;

       while(low<high)

       {

              while(low<high&&L.r[high].key>=pivotkey) --high;

              L.r[low]=L.r[high];

              while(low<high&&L.r[low].key<=pivotkey) ++low;

              L.r[high]=L.r[low];

       }

       L.r[low]=L.r[0];

       return low;

 }

 

void QSort(SqList &L,int low,int high)

{

       int povitloc;

       if(low<high)

       {

              povitloc=Partition(L,low,high);

              QSort(L,low,povitloc-1);

              QSort(L,povitloc+1,high);

       }

}

//简单选择排序

int SelectMinKey(SqList L,int i)

{

       int m;

       for(m=i;m<=L.length;m++)

       {

              if(L.r[m].key<L.r[i].key)

              {

                     i=m;

              }

       }

       return i;

}

void SelectSort(SqList &L)

{

       int i,j;

       RedType temp;

       for(i=1;i<L.length;i++)

       {

              j=SelectMinKey(L,i);

              if(i!=j)

              {

                     temp=L.r[i];

                     L.r[i]=L.r[j];

                     L.r[j]=temp;

              }

       }

}

//堆排序

void HeapAdjust(HeapType &H,int s,int m)

{

       int j;

       RedType rc;

       rc=H.r[s];

       for(j=2*s;j<=m;j*=2)

       {

              if(j<m&&LT(H.r[j].key,H.r[j+1].key))

              {

                     ++j;

              }

              if(!LT(rc.key,H.r[j].key)) break;

              H.r[s]=H.r[j];

              s=j;

       }

       H.r[s]=rc;

}

void HeapSort(HeapType &H)

{

       int i;

       RedType temp;

       for(i=H.length/2;i>0;i--)

       {

              HeapAdjust(H,i,H.length);

       }

       for(i=H.length;i>1;i--)

       {

              temp=H.r[1];

              H.r[1]=H.r[i];

              H.r[i]=temp;

              HeapAdjust(H,1,i-1);

       }

}

int main()

{

       SqList L;

       int n;

       printf("初始化顺序表:");

       InitList(L);

       if(L.length==0)

       {

              printf("顺序表为空!\n");

       }

       printf("输入顺序表的元素个数为:");

       scanf("%d",&n);

       CreateList(L,n);

       printf("输出%d个元素的顺序如下:\n",n);

       DispList(L);

       InsertSort(L);

       printf("直接插入排序结果如下:\n");

       DispList(L);

       QSort(L,1,L.length);

       printf("快速排序结果如下:\n");

       DispList(L);

       SelectSort(L);

       printf("简单选择排序结果如下:\n");

       DispList(L);

       HeapSort(L);

       printf("堆排序结果如下:\n");

       DispList(L);

}

运行情况:

实验体会:

选择排序
缺点
  1. 时间复杂度高。
  2. 不是稳定的排序算法,因为每次找到最小的值后会进行交换位置的操作。
  3. 最坏和最好情况都是O(n²)的复杂度。
优点
  1. 是一种原地排序算法,与冒泡排序相比,交换位置的操作改为了赋值操作,执行效率会提高。
插入排序
缺点
  1. 时间复杂度高。
优点
  1. 有提前终止循环的情况,如果是面对近似有序的数组,效率奇高。
  2. 原地排序不占额外空间,没有交换位置的操作执行效率高。
  3. 是一种稳定的排序算法。
  4. 最好情况能到O(n),(吊打冒泡排序)。
快速排序
缺点
  1. 不是稳定的排序算法。
  2. 分区点的选择有讲究,选择不当时最坏情况会退化为O(n²)。
  3. 需要把待排序的数组一次性读入到内存里。
优点
  1. 速度快。
  2. 原地排序,只需要占用O(logn)的栈空间。
排序
优点

堆排序的平均时间复杂度为nlogn,效率高

排序

实现相对复杂(可以说是这里几种算法中比较难实现的)。

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值