目录
前言
整数排序问题是指将一组无序的整数按照某种规则(如从小到大或从大到小)重新排列的问题。这是一个经典的算法问题,有许多不同的解决方法,如冒泡排序、选择排序、插入排序、快速排序、归并排序、堆排序等。不同的排序算法有不同的时间复杂度和空间复杂度,也有不同的稳定性和适用性。在本实验中,我们将实现和比较几种常用的排序算法,并分析它们的优缺点。
本文中所使用的语言是C语言
1、实验内容
输入一个待排序的序列,分别用选择排序和起泡排序两种排序方法将其变换成有序的序列,输出结果,输出时要求有文字说明。请任选一种语言编写程序实现上述算法,并分析其算法复杂度
2、实验目的
(1)掌握选择排序和起泡排序的基本思想;
(2)掌握两种排序方法的具体实现过程;
(3)在掌握的基础上编程实现两种排序方法。
3、实验步骤
-
根据实验内容设计算法伪代码进行算法描述;
-
利用C++/C/Java等编程语言对算法伪代码进行工程化实现;
-
输入测试用例对算法进行验证;
-
列出算法时间复杂度模型并与计算机运行统计时间进行对比分析。
4、实验过程
1、算法分析
选择排序和冒泡排序是两种常用的排序算法,它们的原理和性能有一些相似之处,也有一些不同之处。本文将对它们进行算法分析,比较它们的时间复杂度和空间复杂度。
选择排序的基本思想是:每次从待排序的序列中选出最小(或最大)的元素,放到已排序的序列的末尾,直到所有元素都排好序。选择排序的时间复杂度为O(n^2),因为它需要进行n-1次比较,每次比较需要遍历n-i个元素,其中i是已排序的元素个数。选择排序的空间复杂度为O(1),因为它只需要一个额外的变量来存储最小(或最大)元素的位置。
冒泡排序的基本思想是:每次从待排序的序列的头部开始,比较相邻的两个元素,如果顺序不对,就交换它们的位置,直到所有元素都排好序。冒泡排序的时间复杂度也为O(n^2),因为它需要进行n-1次遍历,每次遍历需要比较n-i个元素,其中i是已遍历的次数。冒泡排序的空间复杂度也为O(1),因为它只需要一个额外的变量来存储交换时的临时值。
2、写出伪代码
冒泡排序伪代码:for i = 0 to n-1
for j = 0 to n-i-1
if arr[j] > arr[j+1]
swap(arr[j], arr[j+1])
选择排序伪代码:for i = 0 to n-1
min_idx = i
for j = i+1 to n
if arr[j] < arr[min_idx]
min_idx = j
swap(arr[i], arr[min_idx])
3、代码实现
#include <stdio.h>
void bubble_sort(int arr[], int n) {
int i, j;
for (i = 0; i < n-1; i++) {
for (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;
}
}
}
}
void selection_sort(int arr[], int n) {
int i, j;
for (i = 0; i < n-1; i++) {
int min_idx = i;
for (j = i+1; j < n; j++) {
if (arr[j] < arr[min_idx]) {
min_idx = j;
}
}
int temp = arr[i];
arr[i] = arr[min_idx];
arr[min_idx] = temp;
}
}
int main() {
int n;
printf("请输入待排序序列的长度:");
scanf("%d", &n);
int arr[n];
printf("请输入待排序序列:");
for (int i=0; i<n; i++) {
scanf("%d", &arr[i]);
}
printf("原始数组:");
for (int i=0; i<n; i++) {
printf("%d ", arr[i]);
}
printf("\n");
bubble_sort(arr, n);
printf("冒泡排序结果:");
for (int i=0; i<n; i++) {
printf("%d ", arr[i]);
}
printf("\n");
selection_sort(arr, n);
printf("选择排序结果:");
for (int i=0; i<n; i++) {
printf("%d ", arr[i]);
}
printf("\n");
return 0;
}
4、代码详解
这段代码中,bubble_sort函数实现了冒泡排序,selection_sort函数实现了选择排序。在main函数中,用户输入待排序序列的长度和待排序序列本身。然后,原始数组和两种排序结果都被打印出来。
具体地说,bubble_sort函数使用两个嵌套循环来遍历数组中的所有元素。外部循环从第一个元素开始,直到倒数第二个元素。内部循环从第一个元素开始,直到未排序部分的末尾。如果相邻的两个元素顺序不正确,则交换它们。这样一趟下来,最大的元素就会被放在已排序部分的末尾。重复这个过程,直到所有元素都被排好序。
selection_sort函数也使用两个嵌套循环来遍历数组中的所有元素。外部循环从第一个元素开始,直到倒数第二个元素。内部循环从外部循环变量加1开始,直到数组末尾。在内部循环中,找到未排序部分中最小的元素,并将其索引存储在min_idx变量中。然后将该元素与未排序部分的第一个元素交换位置。这样一趟下来,最小的元素就会被放在已排序部分的末尾。重复这个过程,直到所有元素都被排好序。
最后,在main函数中,用户输入待排序序列的长度和待排序序列本身。然后,原始数组和两种排序结果都被打印出来。
5、用例测试
6、复杂度分析
如上文所述,选择排序的时间复杂度为O(n^2),因为它需要进行n-1次比较,每次比较需要遍历n-i个元素,其中i是已排序的元素个数。选择排序的空间复杂度为O(1),因为它只需要一个额外的变量来存储最小(或最大)元素的位置。冒泡排序的时间复杂度也为O(n^2),因为它需要进行n-1次遍历,每次遍历需要比较n-i个元素,其中i是已遍历的次数。冒泡排序的空间复杂度也为O(1),因为它只需要一个额外的变量来存储交换时的临时值。
总结
冒泡排序和选择排序是两种简单的排序算法,可用于对C编程语言中的数组进行排序。冒泡排序的主要区别在于,如果相邻元素的顺序不正确,则通过重复交换相邻元素来操作,而选择排序则通过重复从未排序部分中找到最小元素并将其放置在数组开头来对数组进行排序。
就速度而言,选择排序算法比冒泡排序算法更快,而冒泡排序算法比选择排序算法慢。冒泡排序需要n次,而选择排序需要n^2次。冒泡排序是稳定的算法,而选择排序是不稳定的。与非常缓慢和低效的冒泡排序相比,选择排序算法快速高效。