本期博客来讲述常见的几种排序算法
那么,什么是排序?
排序,就是使一串记录,按照其中的某个或某些关键字的大小,递增或递减的排列起来的操作。有了排序,可以让代码呈现的内容更加明了,格式更容易吸引他人眼球。对一组数据进行有序地排列是经常需要做的事情,所以掌握几种甚至更多的排序算法是绝对有必要的
话不多说,正文开始:
目录
1.冒泡排序
1.概念
冒泡排序适合数据规模很小的时候,因为这种算法的效率比较低。冒泡排序的核心思想是两两比较,将符合某一条件的一者升上去,遍历一次后最小的到了最上面,然后再继续遍历,让剩余最小的继续上升,直到每个元素按照顺序排列完毕。
2.示例
//冒泡排序
#include <stdio.h>
int main()
{
int n = 10;
int a[10] = { 7,4,6,3,0,2,8,9,5,1 };
int temp, i, j;
for (i = 0; i < n - 1; i++) //进行9次比较
for (j = 0; j < n - i - 1; j++)
if (a[j] > a[j + 1]) //升序排序
{
temp = a[j + 1]; //交换相邻的两个元素
a[j + 1] = a[j];
a[j] = temp;
}
printf("排序后为:\n");
for (i = 0; i < n; i++)
printf("%d ", a[i]);
}
2.快速排序
1.概念
快速排序是对冒泡排序的一种改进,核心思想是通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法递归地对这两部分数据分别进行快速排序,从而实现快速排序
2.示例
//快速排序
#include <stdio.h>
#include <stdlib.h>
#define n 10
void show(int array[], int max)
{
int i;
for (i = 0; i < max; i++)
{
printf("%3d", array[i]);
}
printf("\n");
return;
}
void sort(int* arr, int x,int y)
{
if (x < y)
{
int i = x;
int j = y;
int k = arr[x];
while (i < j)
{
while (i < j && arr[j] >= k) // 从右向左找第一个小于k的数
{
j--;
}
if (i < j)
{
arr[i++] = arr[j];
}
while (i < j && arr[i] < k) // 从左向右找第一个大于等于k的数
{
i++;
}
if (i < j)
{
arr[j--] = arr[i];
}
}
arr[i] = k;
// 递归
sort(arr, x, i - 1); // 排序k左边
sort(arr, i + 1, y); // 排序k右边
}
}
int main()
{
int array[n] = { 12,85,25,16,34,23,49,95,17,61 };
int maxlen = n;
printf("排序前\n");
show(array, maxlen);
sort(array, 0, maxlen - 1); // 快速排序
printf("排序后\n");
show(array, maxlen);
return 0;
}
3. 插入排序
1.概念
从第一个元素开始,取下一个元素a,从已排序的元素序列从后往前开始比较,如果该元素大于a,则把这个元素移到下一位。这样一直重复,直到找到已排序元素中小于等于a的元素。把a插入到该元素的后面,如果已排序所有元素都大于a,则将a插入到下标为0的位置。
由于我们一开始不知道元素中哪一部分是已经按照顺序排好的,所以将第一个元素视为已经排好顺序的元素。
时间复杂度:最好情况下为O(N),最坏为O(N*N)
空间复杂度:O(1)
2.示例
//插入排序
#include<stdio.h>
#include<string.h>
#define n 5
void sort(int a[])
{
int i, j, temp;
for (i = 1; i < n; i++)
{
temp = a[i];
if (a[i] < a[i - 1])
{
for (j = i - 1; temp < a[j]; j--)
{
a[j + 1] = a[j];
}
a[j + 1] = temp;
}
}
}
int main()
{
int a[] = { 22,10,12,14,9 };
int i;
printf("排序前:\n");
for (i = 0; i < n; i++)
{
printf("%d ", a[i]);
}
printf("\n排序后:\n");
sort(a);
for (i = 0; i < n; i++)
{
printf("%d ", a[i]);
}
}
4.希尔排序
1.概念
希尔排序是插入排序的改进,又叫作缩小增量排序。由于在某些坏情况时,最小值元素位置若特别靠后,那么前面元素移动次数会很多,影响排序性能。
因此我们就要想办法尽可能早点让小的值靠前,让大的值靠后。它通过先设置一个增量n,大小为数组长度的一半,将间隔为n的元素视作一个组,然后对每个组内部的元素进行从小到大进行插入排序;然后再将增量n缩小一半,再次进行分组插入排序,直到增量n为1,因为增量为1的时候,所有的元素都为同一个组了。
2.示例
//希尔排序
#include<stdio.h>
#include<string.h>
#define n 5
void sort(int a[])
{
int i, j;
int d;
int temp;
//增量变化,d = d/2
for (d = n / 2; d > 0; d /= 2)
{
for (i = d; i < n; i++)
{
//需将a[i]插入有序增量子表中
if (a[i] < a[i - d])
{
temp = a[i];
for (j = i - d; j >= 0 && temp < a[j]; j -= d)
{
a[j + d] = a[j];
}
a[j + d] = temp;
}
}
}
}
int main()
{
int a[] = { 5,40,13,25,10 };
int i;
printf("排序前:\n");
for (i = 0; i < n; i++)
{
printf("%d ", a[i]);
}
printf("\n排序后:\n");
sort(a);
for (i = 0; i < n; i++)
{
printf("%d ", a[i]);
}
}
5.选择排序
1.概念
排序算法核心思想是每一遍从待排序的元素中选出最小(或最大)的一个元素,顺序放在已排好序的数列的最后,直到全部待排序的数据元素排完。
时间复杂度最坏为O(n2),平均为O(n2)。
空间复杂度为O(1)。
2.示例
//选择排序(从小到大)
#include<stdio.h>
int a[10];
int main()
{
int i, k, temp, j;
printf("输入10个数字:\n");
for (int z = 0; z < 10; z++)
scanf_s("%d", &a[z]);
for (i = 0; i < 9; i++)
{
k = i;
for (j = i + 1; j < 10; j++)
{
if (a[j] < a[k])
k = j;
}
if (k != j)
{
temp = a[i];
a[i] = a[k];
a[k] = temp;
}
}
for (i = 0; i < 9; i++)
printf("%d ", a[i]);
printf("%d\n", a[i]);
return 0;
}
6.归并排序
1.概念
核心思想:分治。
这种算法将一个数组不断地通过两两分组的方式进行比较大小,最后直到所有元素都被分到一组里面。
2.示例
#include<stdio.h>
#define N 20
void a1(int arr[], int n) {
int i;
for (i = 0; i < n; i++) {
printf("%2d", arr[i]);
}
}
void merge(int arr[], int x, int y, int z) {
int result[N];
int k = 0;
int i = x;
int j = y + 1;
while (i <= y && j <= z) {
if (arr[i] < arr[j]) {
result[k++] = arr[i++];
}
else {
result[k++] = arr[j++];
}
}
if (i == y + 1) {
while (j <= z)
result[k++] = arr[j++];
}
if (j == z + 1) {
while (i <= y)
result[k++] = arr[i++];
}
for (j = 0, i = x; j < k; i++, j++) {
arr[i] = result[j];
}
}
void sort(int arr[], int start, int end) {
if (start >= end)
return;
int mid = (start + end) / 2;
sort(arr, start, mid);
sort(arr, mid + 1, end);
merge(arr, start, mid, end);
}
int main()
{
int arr[] = { 3, 7, 9, 4, 1, 5, 6, 2, 8, 1 };
sort(arr, 0, 9);
a1(arr, 10);
return 0;
}
7.堆排序
堆排序可以参考 “堆排序”