六种排序方法
(配源代码以及程序实现) NOVA.蒟蒻
代码可能不够简练请大佬们多多包容,本文采用vs2022编写,故有部分优化安全性之处(_s)
排序方法
直接插入排序
冒泡排序
简单选择排序
希尔排序
快速排序
归并排序
(本例题大多采用10个测试用例进行排序)
第一种:直接插入排序
直接插入排序算法就是先将第一个元素认为有序,然后后面的元素与第一个有序元素比较,若比它小则插到前面,若大则位不置变,此时有序序列由一个元素扩充为两个,以此类推。
源代码如下
#include <stdio.h>
int main()
{
int m, n=0, i, j, k,p;
int b[10];
for (i = 0;i < 10;i++)
scanf_s("%d", &b[i]);
n = 10;
for (i = 1;i < n;i++)
{
k = b[i];
for (j = 0;(b[j] < b[i]) && (j < i);j++);
for (p = i;p > j;p--)
b[p] = b[p - 1];
b[j] = k;
}
for (i = 0;i < n;i++)
printf("%d ", b[i]);
}
代码原图及运行如下、
第二种:冒泡排序
每一趟排序都会将最大或最小的元素沉到底部或冒泡到顶部。
源代码如下
#include <stdio.h>
int main()
{
int m, i, k, j, p;
int a[10];
for (i = 0;i < 10;i++)
scanf_s("%d", &a[i]);
for (i = 0;i < 10;i++)
{
for (j = 0;j < 9 - i;j++)
{
if (a[j] > a[j + 1])
{
p = a[j];
a[j] = a[j + 1];
a[j + 1] = p;
}
}
}
for (i = 0;i < 10;i++)
printf("%d ", a[i]);
}
代码原图及运行如下:
、
第三种:简单选择排序
以第一趟为例,引入一个下标min,假设第一个元素最小,min=1,a[min]与a[2]~a[10]的所有元素逐一比较,发现最小的仍是a[1]则此时a[1]进入有序队列,然后将剩下的元素再进行选择排序。
源代码如下:
#include <stdio.h>
int main()
{
int m, n=10, i, j, k, p;
int a[10];
for (i = 0;i < 10;i++)
scanf_s("%d", &a[i]);
for (i = 0;i < 9;i++)
{
p = i;
for (j = i + 1;j < 10;j++)
{
if (a[j] < a[p])
p = j;
}
if (p != i)
{
k = a[p];
a[p] = a[i];
a[i] = k;
}
}
for (i = 0;i < 10;i++)
printf("%d ", a[i]);
}
代码原图及运行如下
第四种:希尔排序
源代码如下:
#include <stdio.h>
int main()
{
int m, n, j, i, p=0, k;
int a[10001];
scanf_s("%d", &m);//此例选择m个测试数据
for (i = 0;i < m;i++)
scanf_s("%d", &a[i]);
for (p= m/2;p >0;p--)
{
for (i = 0;i < m-p;i++)
{
if (a[i] > a[i + p])
{
k = a[i];
a[i] = a[i + p];
a[i +p] = k;
}
}
}
for (i = 0;i < m;i++)
printf("%d ", a[i]);
}
代码原图及运行如下:
第五种:快速排序
源代码如下:
#include <stdio.h>
void kkksort(int* arr, int begin, int end)
{
if (begin > end)//递归结束的标志;
return ;
int tmp = arr[begin];
int i = begin;
int j = end;
while (i != j) {
while (arr[j] >= tmp && j > i)//基点在左端则哨兵先从右边出发;
j--;
while (arr[i] <= tmp && j > i)
i++;
if (j > i) {//如果两哨兵没有相遇,即找到了符合条件的数
// 则交换两个数据;
int t = arr[i];
arr[i] = arr[j];
arr[j] = t;
}
}
arr[begin] = arr[i];//将基点值赋予相遇点值;
arr[i] = tmp;
kkksort(arr, begin, i - 1);//重复进行递归直至所有的基点都已确定;
kkksort(arr, i + 1, end);
}
int main()
{
//以函数递归的形式来进行排序
int m, n, i, k, p, j;
int a[10];
scanf_s("%d", &m);
for (i = 0;i < m;i++)
scanf_s("%d", &a[i]);
kkksort(a, 0, m - 1);
for (i = 0;i < m;i++)
printf("%d ", a[i]);
}
代码原图及运行如下:
第六种:归并排序
源代码如下:
#include <stdio.h>
void merge_sort_recursive(int arr[], int reg[], int start, int end) {
if (start >= end)//当数组长度为一时结束递归;
return;
int len = end - start, mid = (len /2) + start;//拆分数组;
int start1 = start, end1 = mid;
int start2 = mid + 1, end2 = end;
merge_sort_recursive(arr, reg, start1, end1);//分别对两个数组递归
merge_sort_recursive(arr, reg, start2, end2);
int k = start;
//递归结束后开始分装数组;
while (start1 <= end1 && start2 <= end2)
reg[k++] = arr[start1] < arr[start2] ? arr[start1++] : arr[start2++];
//当两个数组都没有结束时,比较两数组中相应的值来得到存储数组中对应位置的值;
while (start1 <= end1)
reg[k++] = arr[start1++];
//若数组二中的值提前排序完毕则将数组一中的值复刻在存储数组的尾部;
while (start2 <= end2)
reg[k++] = arr[start2++];
//若数组一中的值提前排序完毕则将数组一中的值复刻在存储数组的尾部;
for (k = start; k <= end; k++)
arr[k] = reg[k];//重新将存储数组中的序列复刻到原数组;
}
void merge_sort(int arr[], const int len) {
int reg[10001];//首先根据已有数组建立一个存储数组;
merge_sort_recursive(arr, reg, 0, len - 1);
}
int main()
{
//以函数递归的形式来进行排序
int m, n, i, k, p, j;
int a[10];
scanf_s("%d", &m);
for (i = 0;i < m;i++)
scanf_s("%d", &a[i]);
merge_sort(a, m);
for (i = 0;i < m;i++)
printf("%d ", a[i]);
}
代码原图及运行如下:
六种排序好坏比较:
还有几种不太常见的排序方法我待会会与大家分享;希望能给大家的学习带了些许帮助吧。
NOVA.蒟蒻