数据结构:常用排序算法的比较(c++)

一、实验题目

常用的排序算法有冒泡排序、直接插入排序、简单选择排序、快速排序、希尔排序、堆排序等。接下来通过编程逐步分析各种排序。

二、需求分析

[问题描述]
各种内部排序算法的时间复杂度分析结果只给出了算法执行时间的阶,或大概执行时间。试通过随机的数据比较各算法的关键字比较次数和关键字移动次数,以取得直观感受。
[基本要求]
对以下常用的内部排序算法进行比较:起泡排序、直接插入排序、简单选择排序、快速排序、希尔排序、堆排序。
[测试数据]
由随机产生器决定。
[实现提示]
待排序表的表长不少于 100;其中的数据要用伪随机数产生程序产生;至少要用 5 组不同的输入数据作比较;比较的指标为有关键字参加的比较次数和关键字移动次数(关键字交 换计为 3 次移动)。
[选作内容]
对不同的输入表长做试验,观察检查两个指标相关于表长的变化关系。还可以对稳定性
做验证。

三、概要设计

运行代码:

/*彭名驹
2019.12.27
*/
#include<iostream>
#include<string.h>
#include<stdio.h>
#include<stdlib.h>
using namespace std;
#define Max 1000
long bj[Max], yd[Max];
typedef struct {
	int key;
} Data;
long i,j,k;
void show(Data R[], long n) {
	cout<<"结果为:";
	for (i = 1; i <= n; i++)
		cout << R[i].key << " ";
	cout << endl;
}
//冒泡排序
void Maopao(Data R[], long n) {
	Data m[Max], temp;
	for (i = 0; i <= n; i++)
		m[i] = R[i];
	for (i = 1; i < n; i++)
		for (j = 1; j <= n - i; j++) {
			bj[1]++;	                                      //比较次数加1
			if (m[j].key > m[j + 1].key) {
				temp = m[j];
				m[j] = m[j + 1];
				m[j + 1] = temp;
				yd[1] += 3;                                   //移动次数加3
			}
		}
	cout << "冒泡排序";
	show(m, n);
}
//直接插入排序
void zhijiecharu(Data R[], long n) {
	Data r[Max];
	for (i = 0; i <= n; i++)
		r[i] = R[i];
	for (i = 2; i <= n; i++) {
		bj[2]++;                                           //比较次数加1
		if (r[i].key < r[i - 1].key) {                       //需要将r[i]插入有序字表
			r[0] = r[i];
			r[i] = r[i - 1];                               //r[i-1]后移
			for (j = i - 2; r[0].key < r[j].key; j--)
				r[j + 1] = r[j];                           //记录逐个后移,直到找到插入位置
			r[j + 1] = r[0];
			yd[2] += 3;                                    //循环一次移动次数加3
		}
	}
	cout << "直接插入排序";
	show(r, n);
}
//简单选择排序
void Choice(Data R[], long  n) {
	Data c[Max], temp;
	for (i = 0; i <= n; i++)
		c[i] = R[i];
	for (i = 1; i <= n; i++) {                            //在r中选择关键字最小的记录
		k = i;
		for (j = i + 1; j <= n; j++) {
			bj[3]++;	                                 //比较次数加1
			if (c[j].key < c[k].key)
				k = j;		                             //k指向此趟关键字最小的记录
		}
		if (k != i) {
			temp = c[k];
			c[k] = c[i];
			c[i] = temp;
			yd[3] += 3;                                  //移动次数加3
		}
	}
	cout << "简单选择排序";
	show(c, n);
}
//快速排序  枢纽
long Partition(Data R[], long low, long high) {
	//进行一次排序,返回枢纽位置
	R[0] = R[low];                                       //子表第一个记录做枢轴
	yd[4]++;                                             //交换次数加1
	while (low < high) {
		while (low < high&&R[high].key >= R[0].key) {
			bj[4]++;	                                 //比较次数加1
			high--;
		}
		if (low < high) {
			R[low] = R[high];
			low++;
			yd[4]++;	                                //移动次数加1
		}
		while (low < high&&R[low].key <= R[0].key) {
			bj[4]++;
			low++;
		}
		if (low < high) {
			R[high] = R[low];
			high--;
			yd[4]++;
		}
	}
	R[low] = R[0];                                     //枢轴记录到位
	yd[4]++;	                                       //交换次数加1
	return low;	                                       //返回枢轴位置
}
void Quick(Data R[], long low, long high) {
	long n;
	n = high - low + 1;
	//low=1; high=n;
	if (low < high) {
		i = Partition(R, low, high);
		Quick(R, low, i - 1);		              //左子表递归排序
		Quick(R, i + 1, high);			          //右子表递归排序
	}

}
void Quickzhanshi(Data R[], long n) {
	cout << "快速排序";
	show(R, n);
}
//希尔排序
void Shell(Data R[], long sh, long n) {
	//对R做一趟增量是dk的希尔插入排序
	for (i = sh + 1; i <= n; i++) {
		bj[5]++;
		if (R[i].key < R[i - sh].key) {                 //需要将R[i]插入有序增量子表
			R[0] = R[i];
			yd[5]++;
			for (j = i - sh; j > 0 && (R[0].key < R[j].key); j = j - sh) {
				bj[5]++;
				R[j + sh] = R[j];                     //寻找插入位置
				yd[5]++;
			}
			R[j + sh] = R[0];
			yd[5]++;
		}
	}
}
void Shell(Data R[], long n) {
	Data r[Max];
	long i;
	for (i = 1; i <= n; i++)
		r[i] = R[i];
	for (long dk = n; dk >= 1; dk /= 2)
		Shell(r, dk, n);
	cout << "希尔排序";
	show(r, n);
}
//堆调整
void DuiAdjust(Data R[], long s, long m) {
	//假设R[s+1...m]已经是堆,将R[s...m]调整为以R[s]为根的大根堆
	long dj;
	Data dui;
	dui = R[s];
	for (dj = 2 * s; dj <= m; dj = 2 * dj) {
		bj[6]++;
		if (dj < m&&R[dj].key < R[dj + 1].key)
			dj = dj + 1;
		if (dui.key >= R[dj].key)
			break;
		R[s] = R[dj];
		yd[6]++;
		s = dj;
	}
	R[s] = dui;
}
void Duipaixu(Data R[], long n) {
	Data r[Max], dui;
	long i;
	for (i = 1; i <= n; i++)
		r[i] = R[i];
	for (i = n / 2; i > 0; i--)
		DuiAdjust(r, i, n);
	for (i = n; i > 1; i--) {
		dui = r[1];
		r[1] = r[i];
		r[i] = dui;
		yd[6] += 3;
		DuiAdjust(r, 1, i - 1);
	}
	cout << "堆排序";
	show(r, n);
}
int main() {
	long n;
	Data R[Max];
	cout << "数据个数为:" << endl;
	cin >> n;
	for (i = 1; i <= n; i++)
		R[i].key = rand() % 1000;	                      //电脑产生随机数
	cout << "随机产生的数字集合为:" << endl;
	for (i = 1; i <= n; i++)
		cout << R[i].key << " ";
	cout << endl;
	Maopao(R, n);                                     //冒泡排序
	zhijiecharu(R, n);                                     //直接插入排序
	Choice(R, n);                                     //简单选择排序
	Shell(R, n);                                      //希尔排序
	Duipaixu(R, n);                                       //堆排序
	Quick(R, 0, n);                                   //快速排序
	Quickzhanshi(R,n);
	cout << "结果为:" << endl;
	cout << "排序方式" << "比较次数" <<"移动次数" << endl;
	cout << "冒泡排序" <<bj[1] <<"\t\t" << yd[1] << endl;
	cout << "直接插入排序" << bj[2] << "\t\t" << yd[2] << endl;
	cout << "简单选择排序"<< bj[3] << "\t\t" << yd[3] << endl;
	cout << "快速排序" <<  bj[4] << "\t\t" << yd[4] << endl;
	cout << "希尔排序" << bj[5] << "\t\t" << yd[5] << endl;
	cout << "堆排序" <<  bj[6] << "\t\t" << yd[6] << endl;
}

四、调试分析

在这里插入图片描述
调试结果如上图所示,无错误。

五、使用说明

第一步:在程序中输入产生随机数的个数
第二步:程序自动输出相应结果

六、测试结果

在这里插入图片描述

七、其他数据结构实例

数据结构:编程带你了解约瑟夫环
数据结构:简易停车场管理系统
数据结构:哈夫曼编/译码设计
数据结构:图的基本操作模拟-校园导游
数据结构:哈希表设计

以上内容为个人学习总结,如有遗漏或者错误请在评论区中指正!!!

如果看完觉得有所收获的话,记得一键三连哦,谢谢大家!

  • 13
    点赞
  • 60
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 可以使用以下的C语言代码实现: ```c #include <stdio.h> void bubbleSort(int arr[], int n) { int i, j, temp; for (i = 0; i < n-1; i++) { for (j = 0; j < n-i-1; j++) { if (arr[j] < arr[j+1]) { temp = arr[j]; arr[j] = arr[j+1]; arr[j+1] = temp; } } } } int main() { int arr[20], i; printf("请输入20个整数:\n"); for (i = 0; i < 20; i++) { scanf("%d", &arr[i]); } bubbleSort(arr, 20); printf("排序后的结果为:\n"); for (i = 0; i < 20; i++) { printf("%d ", arr[i]); } printf("\n"); return 0; } ``` 在这个代码中,我们定义了一个 `bubbleSort` 函数用于实现冒泡排序算法。然后在 `main` 函数中,我们先读入20个整数,然后调用 `bubbleSort` 函数进行排序,最后输出排序后的结果。注意,在这个算法中,我们是从大到小排序,所以在比较大小时需要将比较符号改为 `<`。 ### 回答2: 起泡法(Bubble Sort)是一种简单排序算法,其基本思想是通过多次遍历数组,依次比较相邻元素的大小,如果顺序不正确,则交换它们的位置,直到所有元素都达到有序状态。 下面是使用C语言实现起泡法对20个数从大到小排序的代码: ```c #include <stdio.h> void bubbleSort(int arr[], int n) { for (int i = 0; i < n-1; i++) { for (int j = 0; j < n-i-1; j++) { if (arr[j] < arr[j+1]) { // 交换两个元素的位置 int temp = arr[j]; arr[j] = arr[j+1]; arr[j+1] = temp; } } } } int main() { int arr[20] = {23, 45, 12, 67, 9, 34, 56, 78, 29, 50, 76, 89, 43, 18, 65, 32, 53, 21, 76, 87}; int n = sizeof(arr) / sizeof(arr[0]); printf("排序前的数组为:"); for (int i = 0; i < n; i++) { printf("%d ", arr[i]); } bubbleSort(arr, n); printf("\n排序后的数组为:"); for (int i = 0; i < n; i++) { printf("%d ", arr[i]); } return 0; } ``` 这段代码首先定义了一个包含20个数的数组arr,然后通过调用bubbleSort函数对数组进行排序。函数中使用了两层嵌套的循环来比较相邻两个元素的大小并进行交换。最后,打印出排序前和排序后的数组。 运行代码,输出结果如下: 排序前的数组为:23 45 12 67 9 34 56 78 29 50 76 89 43 18 65 32 53 21 76 87 排序后的数组为:89 87 78 76 76 67 65 56 53 50 45 43 34 32 29 23 21 18 12 9 可以看到,使用起泡法对数组进行排序,成功地将数组中的数从大到小排列了。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值