七种排序算法

本期博客来讲述常见的几种排序算法

那么,什么是排序?

排序,就是使一串记录,按照其中的某个或某些关键字的大小,递增或递减的排列起来的操作。有了排序,可以让代码呈现的内容更加明了,格式更容易吸引他人眼球。对一组数据进行有序地排列是经常需要做的事情,所以掌握几种甚至更多的排序算法是绝对有必要的

话不多说,正文开始:

目录

1.冒泡排序

1.概念

2.示例

 2.快速排序

1.概念

2.示例

3. 插入排序

1.概念

2.示例

 4.希尔排序

1.概念

2.示例

 5.选择排序

1.概念

2.示例

 6.归并排序

1.概念

 2.示例

 7.堆排序

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.堆排序

堆排序可以参考  “堆排序


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值