C语言排序(桶排序,冒泡排序,选择排序,插入排序,快速排序)

Posted 行稳方能走远

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C语言排序(桶排序,冒泡排序,选择排序,插入排序,快速排序)相关的知识,希望对你有一定的参考价值。

参考:C语言五大排序(桶排序,冒泡排序,选择排序,插入排序,快速排序)动态演示
作者:一只青木呀
发布时间: 2020-09-09 20:18:43
网址:https://blog.csdn.net/weixin_45309916/article/details/108483621

什么是排序?

排序: 把无序变成有序

1、桶排序

概念

桶排序 (Bucket sort)或所谓的箱排序,是一个排序算法,工作的原理是将数组分到有限数量的桶子里。每个桶子再个别排序(有可能再使用别的排序算法或是以递归方式继续使用桶排序进行排序)。桶排序是鸽巢排序的一种归纳结果。当要被排序的数组内的数值是均匀分配的时候,桶排序使用线性时间(Θ(n))。但桶排序并不是 比较排序,他不受到 O(n log n) 下限的影响。

思路

准备桶的时候,桶的大小是原来排序数组中最大元素的值加一,然后遍历无序的数组,把无序数组中的元素的值当成下标给到桶,每存在一个值,桶中的数量就加一。输出的时候,桶的下标值就是之前需要排序的数组的值,只有桶中的数量大于等于一的时候才表示有数据,再进行输出。

demo

#include <stdio.h>
#include <stdlib.h>

int main()
{
	
	//桶排序
	//先准备桶  桶的大小是需要排序数组中的最大元素的值加一
	int app[10] = { 0 };

	//无序的数组
	int arr[9]={5,4,8,6,2,0,3,7,9};
	
	// 遍历无序的数组,把无序数组中的元素的值当成下标给到桶
	for (int i = 0; i < sizeof(arr) / sizeof(int); i++)
	{
		app[arr[i]]++;     
	}
	//输出,把对应的元素出现了几次进行一个输出
	for (int i = 0; i < 10; i++)
	{
		for (int j = 1; j <= app[i]; j++)
		{
			printf("%d ", i);
		}
	}	

	printf("\\n");

	return 0;
}

运行效果

2、冒泡排序

动图演示

概念

冒泡排序(Bubble Sort),是一种计算机科学领域的较简单的排序算法。

它重复地走访过要排序的元素列,依次比较两个相邻的元素,如果顺序(如从大到小、首字母从Z到A)错误就把他们交换过来。走访元素的工作是重复地进行直到没有相邻元素需要交换,也就是说该元素列已经排序完成。

这个算法的名字由来是因为越小的元素会经由交换慢慢“浮”到数列的顶端(升序或降序排列),就如同碳酸饮料中二氧化碳的气泡最终会上浮到顶端一样,故名“冒泡排序”。

思路

每次进行两两比较,大的或者小的就往后移,每进行一次,最后一个数就是已经排好序的了。

demo

#include <stdio.h>

//冒泡排序
void bullerSort(int arr[], int len)
{
	for (int i = 0; i < len - 1; i++)//比较次数
	{
		for (int j = 0; j < len - 1 - i; j++)//比较过程
		{
			if (arr[j]>arr[j + 1])//比较
			{
				//交换
				int temp = arr[j];
				arr[j] = arr[j + 1];
				arr[j + 1] = temp;
			}
		}
	}
}
//输出
void print(int arr[], int len)
{
	for (int i = 0; i < len; i++)
	{
		printf("%d ", arr[i]);
	}
}
int main()
{
	int arr[10]={5,9,11,32,18,54,78,0,87,111};
	bullerSort(arr,10);
	print(arr,10);
	printf("\\n");

	return 0;
}

运行效果

3、选择排序

动图演示

概念

选择排序(Selection-sort)是一种简单直观的排序算法。它的工作原理:首先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置,然后,再从剩余未排序元素中继续寻找最小(大)元素,然后放到已排序序列的末尾。以此类推,直到所有元素均排序完毕。

思路

n个记录的直接选择排序可经过n-1趟直接选择排序得到有序结果。具体算法描述如下:

初始状态:无序区为R[1…n],有序区为空;
第i趟排序(i=1,2,3…n-1)开始时,当前有序区和无序区分别为R[1…i-1]和R(i…n)。该趟排序从当前无序区中-选出关键字最小的记录 R[k],将它与无序区的第1个记录R交换,使R[1…i]和R[i+1…n)分别变为记录个数增加1个的新有序区和记录个数减少1个的新无序区;
n-1趟结束,数组有序化了。

demo

#include <stdio.h>

//选择排序
void selectSort(int arr[], int len)
{
	for (int i = 0; i < len-1; i++)
	{
		int min = i;//假设第一个元素是最小的
		for (int j = i + 1; j < len; j++)
		{
			if (arr[j] < arr[min])
			{
				min = j;//保存最小元素的下标
			}
		}
		//交换
		int temp = arr[min];
		arr[min] = arr[i];
		arr[i] = temp;
	}
}
//输出
void print(int arr[], int len)
{
	for (int i = 0; i < len; i++)
	{
		printf("%d ", arr[i]);
	}
}
int main()
{
	int arr[15]={3,44,38,5,47,15,36,26,27,2,46,4,19,50,48};
	selectSort(arr,15);
	print(arr,15);


	printf("\\n");
	return 0;
}

运行结果

4、插入排序

动图演示

概念

插入排序(Insertion-Sort)的算法描述是一种简单直观的排序算法。它的工作原理是通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入。

思路

一般来说,插入排序都采用in-place在数组上实现。具体算法描述如下:

  • 从第一个元素开始,该元素可以认为已经被排序;
  • 取出下一个元素,在已经排序的元素序列中从后向前扫描;
  • 如果该元素(已排序)大于新元素,将该元素移到下一位置;
  • 重复步骤3,直到找到已排序的元素小于或者等于新元素的位置;
  • 将新元素插入到该位置后;
  • 重复步骤2~5。

demo

#include <stdio.h>

//插入排序
void insertSort(int arr[], int len)
{
	int temp;//保存要插入的元素
	int j;//从当前要要比较插入的元素的前面一个开始
	for (int i = 1; i < len; i++)//第一个元素视为有序,把后面的元素一个一个的插入到前面
	{
		temp = arr[i];
		j = i - 1;
		while (j >= 0&&arr[j]>temp)
		{
			arr[j + 1] = arr[j];//前面的元素往后面移动
			j--;
		}
		arr[j + 1] = temp;//把要插入的元素,插入进对应的位置
	}
}
//输出
void print(int arr[], int len)
{
	for (int i = 0; i < len; i++)
	{
		printf("%d ", arr[i]);
	}
}
int main()
{
	int arr[15]={3,44,38,5,47,15,36,26,27,2,46,4,19,50,48};
	insertSort(arr,15);
	print(arr,15);
	

	printf("\\n");
	return 0;
}

运行效果

5、快速排序

动图演示

概念

快速排序的基本思想:通过一趟排序将待排记录分隔成独立的两部分,其中一部分记录的关键字均比另一部分的关键字小,则可分别对这两部分记录继续进行排序,以达到整个序列有序。

思路

快速排序使用分治法来把一个串(list)分为两个子串(sub-lists)。具体算法描述如下:

  • 从数列中挑出一个元素,称为 “基准”(pivot);
  • 重新排序数列,所有元素比基准值小的摆放在基准前面,所有元素比基准值大的摆在基准的后面(相同的数可以到 任一边)。在这个分区退出之后,该基准就处于数列的中间位置。这个称为分区(partition)操作;
  • 递归地(recursive)把小于基准值元素的子数列和大于基准值元素的子数列排序。

demo

#include <stdio.h>

//快速排序
void quickSort(int arr[], int lift, int right)
{
	if (lift > right)
		return;
	int i = lift, j = right, temp = arr[i];//获取左右和基准数
	while (i < j)
	{
		while (temp < arr[j] && i < j)
			j--;
		if (i < j)
			arr[i++] = arr[j];
		while (temp>arr[i] && i < j)
			i++;
		if (i < j)
			arr[j--] = arr[i];
	}
	arr[i] = temp;

	quickSort(arr, lift, i - 1);//左边
	quickSort(arr, i + 1, right);//右边
}
//输出
void print(int arr[], int len)
{
	for (int i = 0; i < len; i++)
	{
		printf("%d ", arr[i]);
	}
}
int main()
{

	int arr[15]={3,44,38,5,47,15,36,26,27,2,46,4,19,50,48};
	quickSort(arr,0,14);
	print(arr,15);

	printf("\\n");
	return 0;
}

运行结果

以上是关于C语言排序(桶排序,冒泡排序,选择排序,插入排序,快速排序)的主要内容,如果未能解决你的问题,请参考以下文章

你所知道的十大排序算法的总结(冒泡,选择,插入,希尔,归并,快排,堆排序,计数排序,桶排序,基数排序)

九种经典排序算法详解(冒泡排序,插入排序,选择排序,快速排序,归并排序,堆排序,计数排序,桶排序,基数排序)

九大排序算法及其实现- 插入.冒泡.选择.归并.快速.堆排序.计数.基数.桶排序

冒泡排序,快速排序,归并排序,插入排序,希尔排序,堆排序,计数排序,桶排序,基数排序

C++运用循环+数组实现排序的四种常用方法(桶排序冒泡排序选择排序插入排序)

十大排序总结(js实现稳定性内外部排序区别时间空间复杂度冒泡快速直接选择堆直接插入希尔桶基数归并计数排序)