随机生成30个数,试比较直接插入排序、简单选择排序、冒泡排序、快速排序、堆排序和希尔排序的时空性能和稳定性。
来源:互联网 发布:淘宝店铺神笔在哪里 编辑:程序博客网 时间:2024/05/17 23:08
题目
随机生成30个数,试比较直接插入排序、简单选择排序、冒泡排序、快速排序、堆排序和希尔排序的时空性能和稳定性。
源代码
#include<stdio.h>#include<time.h> //产生随机数时时钟做种子#include<stdlib.h>#define MaxSize 50typedef struct{ int key; //记录关键字}RecordType;//直接插入排序void InsertSort(RecordType r[], int length){ for (int i = 2; i < length; i++) { r[0] = r[i]; //将待插入的记录放在监视哨中 int j = i - 1; while (r[0].key < r[j].key) { r[j + 1] = r[j]; j = j - 1; } r[j + 1] = r[0]; //将待插入记录插入到已排序的序列中 }}//简单选择排序void SelectSort(RecordType r[], int length) { int x; //假设待排序列有n个数从第一个开始,以次与其后面的数比较,需要比较n-1次 for (int i = 1; i <= length - 1; i++) { int k = i; for (int j = i + 1; j <= length; j++) //j从2开始 { if (r[j].key < r[k].key) { k = j; } } if (k != i) //当r[j].key>=r[k].key 将r[k]的值借助中间变量X与x[i]的值交换 { x = r[i].key; //r[i].key为最小数 r[i].key = r[k].key; r[k].key = x; } }}//冒泡排序void BubbleSort(RecordType r[], int length){ int t; for (int i = 1; i <= length; i++) { for (int j = 1; j <= length - i - 1; j++) { if (r[j].key > r[j + 1].key) { t = r[j+1].key; r[j + 1].key = r[j].key; r[j].key = t; } } }}//快速排序int QKPass(RecordType r[], int left, int right) //一趟快速排序算法{ int low = left; int high = right; r[0] = r[left]; while (low < high) { while (low<high && r[high].key>r[0].key) { high--; } if (low < high) { r[low] = r[high]; low++; } while (low < high && r[low].key < r[0].key) { low++; } if (low < high) { r[high] = r[low]; high--; } } r[low] = r[0]; return low; //返回基准记录的位置}void QKSort(RecordType r[], int low, int high) //快速排序{ if (low < high) { int pos = QKPass(r, low, high); //调用一趟快速排序,以枢轴元素为界划分两个子区间 QKSort(r, low, pos - 1); //对左部子表进行快速排序 QKSort(r, pos + 1, high); //对右部子表进行快速排序 }}//堆排序void sift(RecordType r[], int n, int m){//对编号为m的节点进行调整 int i = m; r[0] = r[i]; int j = 2 * i; while (j <= n) { if (j < n && r[j].key<r[j + 1].key) { j = j + 1; } if (r[j].key>r[0].key) { r[i] = r[j]; i = j; j = 2 * i; } else { break; } } r[i] = r[0];}void HeapSort(RecordType r[], int length){ //初建堆 int i; for (i = length / 2; i > 0; i--) { sift(r, length, i); } //调整 for (i = length; i > 1; i--) { r[0] = r[1]; r[1] = r[i]; r[i] = r[0]; sift(r, i - 1, 1); }}//希尔排序void ShellInsert(RecordType r[], int length, int delta) //Shell插入,其中delta 为增量{ int i, j; for (i = 1 + delta; i <= length; i++) { if (r[i].key < r[i - delta].key) { r[0] = r[i]; //备份r[i](不做监视哨) for (j = i - delta; j > 0 && r[j].key > r[0].key; j -= delta) { r[j + delta] = r[j]; } r[j + delta] = r[0]; } }}void ShellSort(RecordType r[], int length, int delta[], int n)//希尔排序,delta为增量数组,n为增量数组长度{ for (int i = 0; i < n; i++) { ShellInsert(r, length, delta[i]); }}void ShowResult(RecordType* r, int length) //输出结果{ for (int i = 1; i <= length; i++) { printf("%d\t", r[i]); if (i % 10 == 0) { printf("\n"); } }}void RandNum(RecordType r[MaxSize]){ srand((unsigned)time(NULL)); //初始化随机数 for (int i = 1; i <= 30; i++) { r[i].key = rand() % 100 + 1; //产生1-100之间的随机数 printf("%d\t", r[i]); if (i % 10 == 0) //每行输出10个数 { printf("\n"); } }}void Select(){ printf("------------排序算法-----------\n"); printf("* * * * 1:直接插入排序 * * * *\n"); printf("* * * * 2:简单选择排序 * * * *\n"); printf("* * * * 3: 冒泡排序 * * * *\n"); printf("* * * * 4: 快速排序 * * * *\n"); printf("* * * * 5: 堆排序 * * * *\n"); printf("* * * * 6: 希尔排序 * * * *\n"); printf("-------------------------------\n");}int main(void){ int n, m; RecordType r[31] ; /*delta[] 是希尔排序的增量数组。增量的选取采用的是希尔提出的d=n/2 向下取整, 直到d=1为止的方法,随机产生30个数30/2=15、15/2=7(向下取整的结果)、依次运算 得到增量数组元素为15、7、3、1 */ int delta[] = { 15, 7, 3, 1 }; Select(); do { printf("请选择排序算法:"); scanf("%d", &m); system("cls"); //清屏 switch (m) { case 1: printf("你选择了直接插入排序!\n"); printf("\n"); printf("产生的随机待排序列为:\n"); RandNum(r); InsertSort(r, 30); printf("排序结果为:\n"); ShowResult(r, 30); break; system("cls"); case 2: printf("你选择了简单选择排序!\n"); printf("\n"); printf("产生的随机待排序列为:\n"); RandNum(r); SelectSort(r, 30); printf("排序结果为:\n"); ShowResult(r, 30); break; case 3: printf("你选择了冒泡排序!\n"); printf("\n"); printf("产生的随机待排序列为:\n"); RandNum(r); BubbleSort(r, 30); printf("排序结果为:\n"); ShowResult(r, 30); break; case 4: printf("你选择了快速排序!\n"); printf("\n"); printf("产生的随机待排序列为:\n"); RandNum(r); QKSort(r, 1, 29); printf("排序结果为:\n"); ShowResult(r, 30); break; case 5: printf("你选择了堆排序!\n"); printf("\n"); printf("产生的随机待排序列为:\n"); RandNum(r); HeapSort(r, 30); printf("排序结果为:\n"); ShowResult(r, 30); break; case 6: printf("你选择了希尔排序!\n"); printf("\n"); printf("产生的随机待排序列为:\n"); RandNum(r); ShellSort(r, 30, delta, 4); printf("排序结果为:\n"); ShowResult(r, 30); break; default: printf("输入有误!"); return false; break; } } while (true); return 0;}
时空性能和稳定性
时空性能和稳定性如下表
简要分析
这道题是数据结构-用C语言表示(耿国华 主编)课本第九章 内部排序 课后实习题第一题,当时大二上数据结构时上机偏向随机产生30个数采用题目要求的排序算法:直接插入排序、简单选择排序、冒泡排序、快速排序、堆排序和希尔排序实现对产生的随机数进行排序,再次回顾数据结构这本书,刚好看到这道题,就简单的写了一下,依然偏重产生随机数进行排序,也算是对排序算法的回顾。
这是一道相对简单的编程题,只需要理解排序算法的实现过程,用代码实现,然后利用已有的C语言知识,将代码合理组合起来就可以了。
值得注意的是题目要求随机生成随机数,这就需要使用产生随机数的函数,产生随机数的方法很多,在上面的代码中主要利用rand() 函数,以时间为种子产生随机数,每一次执行程序语句的时间是不同的,所以可以产生不同的随机数,将产生随机数的代码写成函数,具体函数如下:
void RandNum(RecordType r[MaxSize]){ srand((unsigned)time(NULL)); //初始化随机数 for (int i = 1; i <= 30; i++) { r[i].key = rand() % 100 + 1; //产生1-100之间的随机数 printf("%d\t", r[i]); if (i % 10 == 0) //每行输出10个数 { printf("\n"); } }}
由于以时间做种子,使用了srand()函数和rand()函数,所以需要包含头文件
<#include “stdlib.h” 和# include “time.h”;在代码中定义了Select()函数,用于提示用户输入选择,在do -while 语句前调用Select()函数,所以只在在第一次执行时输出提示选择菜单信息,后面的代码中使用了system(“cls”); 进行清屏,确保每次只显示当前产生的随机数和排序结构,提示用户输入选择。
使用switch() 语句,并通过函数调用实现,由于每次都调用定义的函数RandNum(RecordType r[MaxSize]),所以每次进行排序的序列,都是不同的随机数序列。然后,根据用户输入的选择进行相应函数调用,完成排序。通过调试,程序可以成功运行,并实现相应功能。
- 随机生成30个数,试比较直接插入排序、简单选择排序、冒泡排序、快速排序、堆排序和希尔排序的时空性能和稳定性。
- IOS- 快速排序,冒泡排序,直接插入排序和折半插入排序,希尔排序,堆排序,直接选择排序
- 比较排序总结——直接插入排序,希尔排序,选择排序,堆排序,冒泡排序,快速排序,归并排序
- 冒泡排序 快速排序 选择排序 堆排序 直接插入排序 希尔排序 归并排序
- C++实现直接插入排序,折半插入排序,希尔排序,冒泡排序,简单选择排序,快速排序,堆排序
- 直接插入排序 + 希尔排序+ 冒泡排序+ 快速排序 + 直接选择排序 + 堆排序
- 归并排序,堆排序,基数排序,希尔排序,快速排序,交换排序,选择排序和插入排序的总结和比较
- Java基础篇之----排序(快速排序、冒泡排序、堆排序、简单选择排序、 希尔排序、直接插入排序)
- oc中的排序 快速排序,冒泡排序,直接插入排序和折半插入排序,希尔排序,堆排序,直接选择排序
- 排序算法: 冒泡排序, 快速排序,希尔排序,直接插入排序 ,直接选择排序,归并排序,堆排序
- 各种排序算法的稳定性(冒泡、选择、插入、快速、堆排序、希尔排序等)
- 排序总结:插入(简单和改进)、希尔、选择、冒泡、快速、堆排序、归并排序
- 排序算法java版,速度排行:冒泡排序、简单选择排序、直接插入排序、折半插入排序、希尔排序、堆排序、归并排序、快速排序
- 选择排序、快速排序、希尔排序、堆排序不是稳定的排序算法, 冒泡排序、插入排序、归并排序和基数排序是稳定的排序算法。
- 选择排序、快速排序、希尔排序、堆排序不是稳定的排序算法,而冒泡排序、插入排序、归并排序和基数排序是稳定的排序算法。
- 【排序】插入排序,希尔排序,选择排序,冒泡排序,堆排序详解及稳定性分析
- 选择排序、快速排序、希尔排序、堆排序不是稳定的排序算法,而冒泡排序、插入排序、归并排序和基数排序
- 【Java】八个常用的排序算法:插入排序、冒泡排序、选择排序、希尔排序 、快速排序、归并排序、堆排序和LST基数排序
- vue父子传值
- 计算机网络自顶向下方法第四章笔记
- RxJava
- 点击加载圆形进度条,进入扫描二维码界面,接口回调,自定义view/组合view
- 026day(全局,局部,静态变量和变量的作用域,生存期)
- 随机生成30个数,试比较直接插入排序、简单选择排序、冒泡排序、快速排序、堆排序和希尔排序的时空性能和稳定性。
- vmware 虚拟机三种网络模式 桥接 NAT 仅主机区别 是什么意思
- Spring学习笔记之泛型依赖注入
- Oracle 事物
- WordPress上传文件大小限制修改
- matlab函数】conv2、filter2、imfilter的区别
- python_dict
- HDU 5536 Chip Factory
- Apache和Nginx优缺点对比