排序算法在计算机科学和软件开发中具有重要的地位和应用价值。以下是排序算法的重要性和难点的几个方面:
难点
综上所述,排序算法在数据处理和程序优化中具有重要的作用,但同时也面临着时间复杂度、稳定性、适应性和实现复杂度等难点。选择合适的排序算法,并根据具体的需求进行性能优化是一个需要综合考虑多个因素的问题。
基于此,本文对常用的几种排序算法进行实现和解析。
冒泡排序通过不断比较相邻的元素并交换位置,使较大(或较小)的元素逐渐向数组的末尾移动,就像气泡从水中冒出一样,因此得名。具体原理如下:
冒泡排序
#include
#include
using namespace std;
void print(vector<int> num)
{
int s = num.size();
for (int i = 0; i < s; i++)
{
cout << num[i]<<" ";
}
}
int main()
{
vector<int> num;
int n;
int temp;
cin >> n;
for (int i = 0; i < n; i++)
{
int p;
cin >> p;
num.push_back(p);
}
for (int i = 0; i < n; i++)
for (int j = 0; j < n - i-1; j++)
{
if (num[j] > num[j + 1])
{
temp = num[j];
num[j] = num[j + 1];
num[j + 1] = temp;
}
}
print(num);
return 0;
}
以上代码通过冒泡排序实现了数组中的数由小到大重排。冒泡排序通过相邻元素的比较和交换,将较大的元素逐渐“冒泡”到数组的末尾。它是一种简单但效率较低的排序算法。
选择排序每次从未排序的部分中选择最小(或最大)的元素,并将其放置在已排序部分的末尾。具体原理如下:
选择排序
#include
#include
using namespace std;
void print(vector<int> &num)
{
int s = num.size();
for (int i = 0; i < s; i++)
{
cout << num[i] << " ";
}
}
int main()
{
vector<int> num;
int n;
int temp;
cin >> n;
int min = 0;
for (int i = 0; i < n; i++)
{
int p;
cin >> p;
num.push_back(p);
}
for (int i = 0; i < n; i++)
{
min = i;
for (int j = i; j < n ; j++)
{
if(num[min]>num[j])
{
min=j;
}
}
if (i != min)
{
int temp = num[i];
num[i] = num[min];
num[min] = temp;
}
}
print(num);
return 0;
}
选择排序每次从未排序的部分中选择最小(或最大)的元素,并将其放置在已排序部分的末尾。它的主要优点是简单易实现。
插入排序将数组分为已排序和未排序两部分,每次从未排序部分中取出一个元素,并将其插入到已排序部分的正确位置。具体原理如下:
插入排序
#include
#include
using namespace std;
void print(vector<int> &num)
{
int s = num.size();
for (int i = 0; i < s; i++)
{
cout << num[i] << " ";
}
}
int main()
{
vector<int> num;
int n;
int temp;
cin >> n;
for (int i = 0; i < n; i++)
{
int p;
cin >> p;
num.push_back(p);
}
for (int i = 1; i < n; i++)
{
for (int j = i-1; j>=0; j--)
{
if (num[j] > num[j+1])
{
temp = num[j];
num[j] = num[j+1];
num[j+1] = temp;
}
else break;
}
}
print(num);
return 0;
}
插入排序通过将数组分为已排序和未排序两部分,每次从未排序部分中取出一个元素并插入到已排序部分的正确位置。它对于小型数组或部分有序的数组表现良好。
快速排序是一种基于分治法的排序算法。它通过选择一个基准元素,将数组分割为小于基准的部分和大于基准的部分,然后对两部分分别进行递归排序。具体原理如下:
快速排序
#include
#include
#include
using namespace std;
void print(vector<int> &num)
{
int s = num.size();
for (int i = 0; i < s; i++)
{
cout << num[i] << " ";
}
}
void sort(vector<int> &num, int low, int high)
{
int i = low;
int j = high;
int temp = num[low];//flag
if (i >= j)
return;
while (i != j)
{
while (num[j] >= temp && i < j)
j--;
while (num[i] <= temp && i < j)
i++;
if (i < j)
{
swap(num[i], num[j]);
}
}
swap(num[low], num[i]);
sort(num, low, i - 1);
sort(num, i + 1, high);
}
int main()
{
vector<int> num;
int n;
int low, high;
low = 0;
cin >> n; high = n;
for (int i = 0; i < n; i++)
{
int p;
cin >> p;
num.push_back(p);
}
sort(num, low, high-1);
print(num);
return 0;
}
快速排序通过选择一个基准元素,将数组分割为小于基准的部分和大于基准的部分,然后对两部分分别进行递归排序。它是一种高效的排序算法。
归并排序是一种稳定的排序算法,它通过将数组递归地分成两半,对每个子数组进行排序,然后将两个有序子数组合并成一个有序数组。具体原理如下:
#include
#include
using namespace std;
void print(vector<int>& num) {
int s = num.size();
for (int i = 0; i < s; i++) {
cout << num[i] << " ";
}
}
void merge(vector<int>& num, int first, int mid, int last, vector<int>& nums) {
int i = first, j = mid + 1;
int n = last;
int k = 0;
while (i <= mid && j <= last) {
if (num[i] < num[j])
nums[k++] = num[i++];
else
nums[k++] = num[j++];
}
while (i <= mid)
nums[k++] = num[i++];
while (j <= last)
nums[k++] = num[j++];
// 将排序好的子数组复制回原始数组
for (int p = 0; p < k; p++) {
num[first + p] = nums[p];
}
}
void mergesort(vector<int>& num, int first, int last, vector<int>& nums) {
if (first < last) {
int mid = (first + last) / 2;
mergesort(num, first, mid, nums);
mergesort(num, mid + 1, last, nums);
merge(num, first, mid, last, nums);
}
}
int main() {
vector<int> num;
vector<int> nums;
int n;
cin >> n;
for (int i = 0; i < n; i++) {
int p;
cin >> p;
num.push_back(p);
nums.push_back(0);
}
mergesort(num, 0, n - 1, nums);
print(num);
return 0;
}
print 函数用于打印给定数组 num 中的元素。
merge 函数是归并排序中的关键步骤,用于将两个有序的子数组合并成一个有序数组。
函数参数 num 是原始数组,first 是第一个子数组的起始索引,mid 是第一个子数组的结束索引,last 是第二个子数组的结束索引,nums 是辅助数组用于存储排序结果。
首先定义变量 i 和 j 分别指向两个子数组的起始位置,k 用于遍历辅助数组 nums。
在一个循环中,比较 num[i] 和 num[j],将较小的元素放入 nums[k],然后将相应的索引 i 或 j 增加 1。
然后,将剩余的未遍历完的子数组中的元素依次放入 nums 中。
最后,将排序好的子数组复制回原始数组 num 中。
mergesort 函数是归并排序的递归函数。
函数参数 num 是原始数组,first 是第一个子数组的起始索引,last 是第二个子数组的结束索引,nums 是辅助数组用于存储排序结果。
首先检查递归结束的条件,即当 first 小于 last 时。
然后计算出中间索引 mid,并递归调用 mergesort 函数对左半部分和右半部分进行排序。
最后,调用 merge 函数将排序好的子数组合并成一个有序数组。
main 函数是程序的入口。
首先定义了两个空的整数向量 num 和 nums。
输入变量 n 表示待排序数组的大小。
使用循环从标准输入中读取 n 个整数,并将其添加到 num 向量中,同时将初始值 0 添加到 nums 向量中。
调用 mergesort 函数对 num 进行归并排序,并传入辅助数组 nums。
最后调用 print 函数打印排序后的数组。