《数据结构与算法统计》实验报告——实验四学院:班级:学号:姓名:一、实验目的1、熟悉VC 环境,学会使用C 语言利用顺序表解决实际问题。
2、通过上机、编程调试,加强对线性表的理解和运用的能力。
3、锻炼动手编程,独立思考的能力。
二、实验内容从键盘输入10个数,编程实现分别用插入排序、交换排序、选择排序算法进行排序,输出排序后的序列。
三、程序设计1、概要设计为了实现排序的功能,需要将输入的数字放入线性表中,进行进一步的排序操作。
(1)抽象数据类型:ADT SqList{数据对象:D={|,1,2,,,0}i i a a ElemSet i n n ∈=≥数据关系:R1=11{,|,,1,2,,}i i i i a a a a D i n --<>∈= 基本操作:InPut(SqList &L)操作结果:构造一个线性表L 。
OutPut(SqList L)初始条件:线性表L 已存在。
操作结果:按顺序在屏幕上输出L 的数据元素。
InsertSort(SqList &L)初始条件:线性表L 已存在。
操作结果:对L 的数据元素进行插入排序。
QuickSort(SqList &L)初始条件:线性表L 已存在。
操作结果:对L 的数据元素进行快速排序。
SelectSort(SqList &L)初始条件:线性表L 已存在。
操作结果:对L 的数据元素进行选择排序。
}ADT SqList⑵主程序流程由主程序首先调用InPut(L)函数创建顺序表,调用InsertSort(L)函数进行插入排序,调用OutPut(L)函数显示排序结果。
再由主程序首先调用InPut(L)函数创建顺序表,调用QuickSort(L)函数进行交换排序,调用OutPut(L)函数显示排序结果。
再由主程序首先调用InPut(L)函数创建顺序表,调用SelectSort(L)函数进行选择排序,调用OutPut(L)函数显示排序结果。
⑶模块调用关系由主函数模块调用创建顺序表模块,排序模块与显示输出模块。
⑷流程图2、详细设计(1)数据类型设计#define MAXSIZE 15//用作示例的小顺序表的最大长度typedef struct{int key;//关键字项int otherinfo;//其它数据项}RedType;//记录类型typedef struct{RedType r[MAXSIZE+1];//r[0]闲置或用作哨兵单元int length;//顺序表长度}SqList;//顺序表类型(2)操作算法设计void InPut(SqList &L)//输入数字,创建顺序表{int i;printf("请输入10个数字:\n");L.length=10;for(i=1;i<=L.length;i++){scanf("%d",&L.r[i].key);}}void InsertSort(SqList &L)//对顺序表L作直接插入排序{int i,j;for(i=2;i<=L.length;i++){if(L.r[i].key<L.r[i-1].key)//如果“<”,需将L.r[i]插入有序子表{L.r[0].key=L.r[i].key;//复制为哨兵L.r[i].key=L.r[i-1].key;for(j=i-2;L.r[0].key<L.r[j].key;j--){L.r[j+1].key=L.r[j].key;//记录后移}L.r[j+1].key=L.r[0].key;//插入到正确位置}}}int Partition(SqList &L,int low,int high)//交换顺序表L中子表r[low…high]的记录,枢轴记录到位,并返回其所在位置,/此时在它之前(后)的记录均不大(小)于它。
{int pivotkey;L.r[0].key=L.r[low].key;//用子表的第一个记录作枢轴记录pivotkey=L.r[low].key;//枢轴记录关键字while(low<high)//从表的两端交替地向中间扫描{while(low<high&&L.r[high].key>=pivotkey){--high;//将比枢轴记录小的记录移到低端}L.r[low].key=L.r[high].key;while(low<high&&L.r[low].key<=pivotkey){++low;//将比枢轴记录大的记录移到高端}L.r[high].key=L.r[low].key;}L.r[low].key=L.r[0].key;//枢轴记录到位return low;//返回枢轴位置}void QSort(SqList &L,int low,int high)//对顺序表L中的子序列L.r[low…high]作快速排序{int pivotloc;if(low<high)//长度大于1{pivotloc=Partition(L,low,high);//将L.r[low…high]一分为二QSort(L,low,pivotloc-1);//对低子表递归排序,pivotloc是枢轴位置QSort(L,pivotloc+1,high);//对高子表递归排序}}void QuickSort(SqList &L)//对顺序表L做快速排序{QSort(L,1,L.length);}void SelectSort(SqList &L)//对顺序表L作简单选择排序{int i,j,k;for(i=1;i<L.length;i++)//选择第i小的记录,并交换到位{k=i;for(j=i+1;j<L.length;j++)//在L.r[i…L.length]中选择key最小的记录{if(L.r[j].key<L.r[k].key){k=j;}}if(i!=k)//与第i个记录交换{L.r[0].key=L.r[i].key;L.r[i].key=L.r[k].key;L.r[k].key=L.r[0].key;}}}void OutPut(SqList L)//输出顺序表{int i;for(i=1;i<=L.length;i++){printf("%d ",L.r[i].key);}printf("\n");}⑶主函数设计void main()//主程序{SqList L;printf("插入排序法:\n");InPut(L);//创建线性表LInsertSort(L);//对L进行插入排序OutPut(L);//输出线性表Lprintf("交换排序法:\n");InPut(L);//创建线性表LQuickSort(L);//对L进行交换排序OutPut(L);//输出线性表Lprintf("选择排序法:\n");InPut(L);//创建线性表LSelectSort(L);//对L进行选择排序OutPut(L);//输出线性表L}四、程序调试分析⑴在快速排序中,对一些后引入的变量,如pivotkey没有声明,导致编译失败。
⑵在直接插入排序中,由于对程序理解不深,将if的{}扩错了位置,导致程序不能按预期输出。
五、程序运行结果测试一:插入排序法:请输入10个数字:1 3 5 7 92 4 6 8 00 1 2 3 4 5 6 7 8 9交换排序法:请输入10个数字:1 3 5 7 92 4 6 8 00 1 2 3 4 5 6 7 8 9选择排序法:请输入10个数字:1 3 5 7 92 4 6 8 01 2 3 4 5 6 7 8 9 0测试二:插入排序法:请输入10个数字:49 38 65 97 76 13 27 67 52 3413 27 34 38 49 52 65 67 76 97交换排序法:请输入10个数字:49 38 65 97 76 13 27 67 52 3413 27 34 38 49 52 65 67 76 97选择排序法:请输入10个数字:49 38 65 97 76 13 27 67 52 3413 27 38 49 52 65 67 76 97 34六、程序清单#include <iostream>#include <stdio.h>#define MAXSIZE 15//用作示例的小顺序表的最大长度typedef struct{int key;//关键字项int otherinfo;//其它数据项}RedType;//记录类型typedef struct{RedType r[MAXSIZE+1];//r[0]闲置或用作哨兵单元int length;//顺序表长度}SqList;//顺序表类型void InPut(SqList &L);void InsertSort(SqList &L);void OutPut(SqList L);void QuickSort(SqList &L);void QSort(SqList &L,int low,int high);void SelectSort(SqList &L);void main()//主程序{SqList L;printf("插入排序法:\n");InPut(L);//创建线性表LInsertSort(L);//对L进行插入排序OutPut(L);//输出线性表Lprintf("交换排序法:\n");InPut(L);//创建线性表LQuickSort(L);//对L进行交换排序OutPut(L);//输出线性表Lprintf("选择排序法:\n");InPut(L);//创建线性表LSelectSort(L);//对L进行选择排序OutPut(L);//输出线性表L}void InPut(SqList &L)//输入数字,创建顺序表{int i;printf("请输入10个数字:\n");L.length=10;for(i=1;i<=L.length;i++){scanf("%d",&L.r[i].key);}}void InsertSort(SqList &L)//对顺序表L作直接插入排序{int i,j;for(i=2;i<=L.length;i++){if(L.r[i].key<L.r[i-1].key)//如果“<”,需将L.r[i]插入有序子表{L.r[0].key=L.r[i].key;//复制为哨兵L.r[i].key=L.r[i-1].key;for(j=i-2;L.r[0].key<L.r[j].key;j--){L.r[j+1].key=L.r[j].key;//记录后移}L.r[j+1].key=L.r[0].key;//插入到正确位置}}}int Partition(SqList &L,int low,int high)//交换顺序表L中子表r[low…high]的记录,枢轴记录到位,并返回其所在位置,//此时在它之前(后)的记录均不大(小)于它。