数据结构实验报告六(排序实…

 

 

数据结构与算法课程实验报告

 

 

 

 

实验六:排序实践

                  

 

 

 

 

 

 

 

                    

 

 

姓名:

班级:               

学号: 

 

 

 

 

 

 

 

 

 

 

实验六 排序实践

一.实验内容:

      实现各排序算法,必须实现起泡排序、希尔排序和简单选择排序,其他排序算法选做,并分析各算法的性能。

二.实验目的:

     掌握各排序算法的实现方法,并分析各排序算法的时间和空间性能。

三:问题描述:

希尔排序:在每趟排序前,先设置一个增量,将整个待排记录序列逐段分割成若干个子序列分别进行直接插入排序,待整个序列中的记录“基本有序”时,再对全体记录进行一次直接插入排序。

起泡排序:第一趟起泡排序是将第一个记录的关键字和第二个记录的关键字进行比较,若为逆序,则将两个记录交换,然后比较第二个记录和第三个记录的关键字。以此类推,直到将第n-1个记录和第n个记录的关键字进行比较过为止。再进行第二趟起泡排序,直到在一趟排序过程中没有进行过交换记录的操作为止。

简单选择排序:通过n-i次关键字间的比较,从n-i+1个记录中选择出关键字最小的记录,并和第i1<=i<=n)个记录交换。

四:问题实现

1.定义了两个数据结构,记录类型和顺序表类型。

typedef struct

{

      int key;         //关键字项

}RedType;           //记录类型

 

typedef struct

{

RedType r[MAX+1];  //r[0]做监视哨或暂存空间,MAX 20 为顺序表的最大长度

int length;   //顺序表长度

}SqList;  //顺序表类型。

2.主要实现思路:将待排序的序列存放在顺序表里,再进行相应的排序,每个排序都有初始关键字、每趟排序结果、最终排序结果的显示。

希尔排序:要自定义排序的趟数和每趟排序的增量,增量存放在一个数组里。主要是通过比较关键字的大小,记录后移,找到插入位置,然后插入。

起泡排序:设置了一个标记 flag;用于标记排序是否结束,flag=1继续,flag=0结束。主要是通过两两比较,每次都选出一个无序区里最大的关键字,直到全部有序为止。

简单选择排序:定义了一个函数SelectMinKey(SqList &L,int i)返回key最小的记录的下标。主要是选择关键字最小的记录的操作。

五:主要源程序代码(包含程序备注)

1.顺序表的初始化

SqList InitSqList(SqList &L)

{

      int N;

      cout<<"请输入待排序数据的个数N="<<endl;

      cin>>N;

      L.length=N+1;

      return L;

}

2.顺序表的创建

SqList CreateSqList(SqList &L)

{

      InitSqList(L);

    cout<<"请输入待排序的数据"<<endl;

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

      {

           cout<<"L.r["<<i<<"].key=";

           cin>>L.r[i].key;

      }

      return L;

}

3.定义SelectMinKey(SqList &L,int i)函数,返回key最小的记录的下标。

int SelectMinKey(SqList &L,int i)

{

      int j;//v记录关键字最小的记录的下标

      int v=i;

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

      {

           if(L.r[j].key<L.r[v].key)v=j;

      }

      return v;

}

4. 简单选择排序的实现

void SelectSort(SqList &L)//对顺序表L作简单选择排序

{

      cout<<"初始关键字 ";

      for(int j1=1;j1<L.length;j1++)cout<<" "<<L.r[j1].key;

      int j;

      int count=0;//记录排序趟数

 

      for(int i=1;i<L.length;i++)   //选择第i小的记录,并交换到位

      {

       j=SelectMinKey(L,i);    //选择key最小的记录

         if(i!=j)                    //与第i个记录交换

         {

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

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

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

         }

         count++;   

           cout<<endl<<count<<"趟排序结果:";

           for(int j2=1;j2<L.length;j2++)cout<<" "<<L.r[j2].key;

      }

}

5.起泡排序的实现

void BubbleSort(SqList &L)

{

      cout<<"初始关键字 ";

      for(int j1=1;j1<L.length;j1++)cout<<" "<<L.r[j1].key;

 

      int count=0;//记录排序趟数

      int flag=1;//用于标记排序是否结束,flag=1继续,flag=0结束

      int m=L.length-2;//m用于记录无序区的个数,初始为n-1,因为L.r[0]不放数据,所以L.length=n+1

      while((m>0)&&(flag==1))   //m=0说明数据已全部有序

      {

           flag=0;

           for(int i=1;i<=m;i++)

           {

                 if(L.r[i].key>L.r[i+1].key)

                 {

                flag=1;

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

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

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

                 }

           }

           m--;

           count++;   

           cout<<endl<<count<<"趟排序结果:";

           for(int j2=1;j2<L.length;j2++)cout<<" "<<L.r[j2].key;

      }

}

6.一趟希尔排序的实现

void ShellInsert(SqList &L,int d) // L.r[0]是暂存单元,不是哨兵。j<=0时,插入位置已找到

{

      int j;

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

      {

           if(L.r[i].key<L.r[i-d].key)

           {

                 L.r[0]=L.r[i];//L.r[i]插入有序增量子表,暂存在L.r[0]

                 for(j=i-d;j>0&&(L.r[0].key<L.r[j].key);j-=d)

                 {

                      L.r[j+d]=L.r[j];         //记录后移,查找插入位置

                 }

                 L.r[j+d]=L.r[0];      //插入位置已找到,插入

 

           }

      }

}

 

7. t趟希尔排序的实现

void ShellSort(SqList &L)

{

      int t;

      int dk[MAX];

      cout<<"请输入排序趟数"<<endl;

      cin>>t;

      cout<<"请输入增量序列,要求没有除1外的公因子"<<endl;

      for(int i=0;i<t;i++)

      {

           cin>>dk[i];

      }

      while(dk[t-1]!=1)

      {

           cout<<"最后一个增量值必须为1"<<endl;

      }

      cout<<"初始关键字 ";

      for(int j1=1;j1<L.length;j1++)cout<<" "<<L.r[j1].key;

      for(int k=0;k<t;k++)

      {

           ShellInsert(L,dk[k]);

           cout<<endl<<k+1<<"趟排序结果:";

           for(int j2=1;j2<L.length;j2++)cout<<" "<<L.r[j2].key;

      }

     

     

}

 

8.主程序

void main()

{ 

      int ch,n=1; 

      do

      {

           SqList L;

          CreateSqList(L);

           cout<<"1.简单选择排序;2.冒泡排序;3.希尔排序"<<endl;

          cin>>ch;

           switch(ch)

           {

           case 1:SelectSort(L);

                 break;

           case 2:BubbleSort(L);

                 break;

           case 3:ShellSort(L);

                 break;       

           }

           cout<<endl<<endl<<"排序后:"<<endl;

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

           {

                 cout<<" "<<L.r[i].key;

           }

 

           do

           {

           cout<<endl<<endl<<"1.继续;2.退出"<<endl;

           cin>>n;          

           }while(n!=1&&n!=2);

      }while(n==1);

     

}

 

六:总结

在设计希尔排序的增量时,存在一些问题。我设计的是让用户自己定义要排序的趟数,和每趟排序的增量,并且设置了最后一趟增量必须为1,但其他没有强制设置。

  • 8
    点赞
  • 35
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
数据结构与算法树验的目的是掌握树型结构的基本概念和算法,以及二叉树的存储结构和遍历方法。验要求学生能够设计数据结构和有效算法,用高级语言编程现并测试其正确性和有效性。\[1\] 在验中,学生需要编写程序来建立二叉树的二叉链表存储结构,并展示和保存二叉树的形式。同时,需要现二叉树的先序、中序、后序和层序遍历的递归和非递归算法,并展示和保存相应的遍历序列。此外,还需要完成给定二叉树的完全二叉树判断或求任意两个节点的公共祖先的应用任务。\[2\] 关于数据结构与算法树验的更多内容和实验报告更新可以参考博客专栏:https://blog.csdn.net/weixin_43598687/category_11640051.html\[3\] #### 引用[.reference_title] - *1* *2* [《数据结构与算法》验:树型结构的建立与遍历](https://blog.csdn.net/gzn00417/article/details/104145492)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] - *3* [本科课程【数据结构与算法】验5 - 广度优先搜索、二叉排序树的构造](https://blog.csdn.net/weixin_43598687/article/details/123617469)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值