C语言之快速排序算法(递归Hoare版)介绍

废话不多说,先看代码

#define  _CRT_SECURE_NO_WARNINGS 1
//快速排序算法,递归求解
#include <stdio.h>
void swap(int* a, int* b)
{
	int c = 0;
	c = *a;
	*a = *b;
	*b = c;
}
void Compare(int arr[], int one, int end)
{
	int first = one;//最左边数组下标
	int last = end;//最右边数组下标
	int key = first;//用于比较的标量(选取最左边第一个元素)
	if (first >= last)
	{
		return;
	}
	while (first < last)
	{
		while (first < last && arr[last] >= arr[key])//右边找比标量小的数
		{
			last--;
		}
		while (first < last && arr[first] <= arr[key])//左边找比标量大的数
		{
			first++;
		}
		if(first < last)//分析交换找出来的值
		swap(&arr[first], &arr[last]);
	}
	if (first == last)
	{
		int mite = key;//交换标量到它应该到的位置上,重新选取标量
		swap(&arr[mite], &arr[last]);
	}
	Compare(arr,one,first-1);//左边递归排序
	Compare(arr,first+1,end);//右边递归排序
}
int main()
{
	int arr[] = { 5,4,6,5,2,1};
	int i = 0;
	int len = sizeof(arr) / 4;
	Compare(arr,i,len-1);//传第一个和最后一个元素的下标
	for (i = 0; i < len; i++)
	{
		printf("%d ", arr[i]);
	}
	return 0;
}

首先什么是快速排序算法:快速排序是由东尼·霍尔所发展的一种排序算法。在平均状况下,排序n 个项目要Ο(nlogn) 次比较。在最坏状况下则需要Ο(n2) 次比较,但这种状况并不常见。事实上,快速排序通常明显比其他 Ο(nlogn) 算法更快,因为它的内部循环(inner loop)可以在大部分的架构上很有效率地被实现出来。

快速排序的最坏运行情况是 O(n²),比如说顺序数列的快排。但它的平摊期望时间是 O(nlogn),且 O(nlogn) 记号中隐含的常数因子很小,比复杂度稳定等于 O(nlogn) 的归并排序要小很多。所以,对绝大多数顺序性较弱的随机数列而言,快速排序总是优于归并排序。

快速排序使用分治法(Divide and conquer)策略来把一个串行(list)分为两个子串行(sub-lists)

简单的说,选取一个基准(这里选取第一个数据),与其他数据进行比较,使比它小的在它的前面,比它大的在它的后面。然后再以这个基准为界限分为两部地方(比它大的部分、比它小的部分),分别选取两个部分的基准,再进行比较,比较完后在进行分界,重复下去,直到最后每部分都只有一个数据时,排序结束。

图解-->

代码讲解:<运用递归>

1、首先需要创建数组、数组第一个数据下标,最后一个数据下标三个参数,数组用于储存数据,然后创建一个Compare()用于快速排序函数,最后打印出来就是我们需要的有序数列。

int main()
{
	int arr[] = { 5,4,6,5,2,1};
	int i = 0;
	int len = sizeof(arr) / 4;
	Compare(arr,i,len-1);//传第一个和最后一个元素的下标
	for (i = 0; i < len; i++)
	{
		printf("%d ", arr[i]);
	}
	return 0;

2、Compare()函数创建

这里使用无符号返回类型,因为不需要返回值

为保证数组第一个元素和最后一个元素下标不变,创建first和last两个局部变量记录数组第一个元素和最后一个元素的下标

创建key下标的数据作为基准

void Compare(int arr[], int one, int end)
{
	int first = one;//最左边数组下标
	int last = end;//最右边数组下标
	int key = first;//用于比较的标量(选取最左边第一个元素)

3、首先判断数列是否只有一个元素,如果只有一个元素,则函数结束。

4、开始实现函数主要比较部分

4.1、如果选取左边第一个数据为基准,先从右边开始比较,

4.2、从右边第一个数据开始与key进行比较,如果比它大则继续向右比较(last--),直到找到比key小的数据,便停下来。

4.3、此刻开始从左边开始与key比较,如果比key小则继续比较(first++),如果比key大则与右边找到的比key大的数进行交换。然后右边继续找,重复以上步骤。

4.4、直到first>=last时,都停止寻找,并交换此时first下标的数据与key的值

4.5、分治思想,以此时的key下标的数组作为分界,分为比它大的、比它小的两部分,在重复以上步骤,直至只有一个数据为止,停下排序。采用递归求解。

void Compare(int arr[], int one, int end)
{
	int first = one;//最左边数组下标
	int last = end;//最右边数组下标
	int key = first;//用于比较的标量(选取最左边第一个元素)
	if (first >= last)
	{
		return;
	}
	while (first < last)
	{
		while (first < last && arr[last] >= arr[key])//右边找比标量小的数
		{
			last--;
		}
		while (first < last && arr[first] <= arr[key])//左边找比标量大的数
		{
			first++;
		}
		if(first < last)//分析交换找出来的值
		swap(&arr[first], &arr[last]);
	}
	if (first == last)
	{
		int mite = key;//交换标量到它应该到的位置上,重新选取标量
		swap(&arr[mite], &arr[last]);
	}
	Compare(arr,one,first-1);//左边递归排序
	Compare(arr,first+1,end);//右边递归排序
}

swap()交换函数,因为需要影响到交换函数外的值,使用指针形参。

void swap(int* a, int* b)
{
	int c = 0;
	c = *a;
	*a = *b;
	*b = c;
}

到此这篇关于C语言之快速排序算法(递归Hoare版)介绍的文章就介绍到这了,更多相关C语言快速排序算法内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • C语言数据结构与算法之排序总结(一)

    目录 一.前言 二.基本概念 1.排序 2.排序方法的稳定性 3.内部和外部排序 三.插入类排序 1.直接插入排序 2.折半插入排序 3.希尔排序 四.交换类排序 1.冒泡排序 2.快速排序 五.总结比较 一.前言 学习目标: 排序和查找密不可分,将待处理的数据按关键值大小有序排列后,查找更加快速准确 理解各种排序算法的定义和特点,并能将代码灵活运用 掌握各种排序方法时间复杂度与空间复杂度 理解排序稳定和不稳定的概念                 重点和难点: 希尔.快速.堆.归并排序这几种快

  • C语言 八大排序算法的过程图解及实现代码

    目录 前言 一.插入排序 时间复杂度 空间复杂度 代码实现(升序) 二.希尔排序 时间复杂度 空间复杂度 代码实现 三.选择排序 时间复杂度 空间复杂度 代码实现 四.堆排序 时间复杂度 空间复杂度 代码实现 五.冒泡排序 时间复杂度 空间复杂度 代码实现 六.快排排序 时间复杂度 空间复杂度 代码实现 七.归并排序 时间复杂度 空间复杂度 代码实现 八.计数排序 时间复杂度 空间复杂度 九.各种排序总结比较 前言 排序是数据结构中很重要的一章,先介绍几个基本概念. 排序稳定性:多个具有相同的关

  • C语言数据结构与算法之排序总结(二)

    目录 一.前言 二.选择类排序 1.简单选择排序 2.树形选择排序 3.堆选择排序 三.归并排序 四.分配类排序 1.多关键字排序 2.链式基数排序 五.总结归纳 一.前言 之前的排序总结(一)对插入类和交换类排序作了比较详细的总结,对于直接插入.希尔排序.冒泡排序.快速排序要求熟练掌握 这篇排序全面总结(二)主要介绍选择类排序中的简单.树形和堆排序,归并排序.分配类排序的基数排序 二.选择类排序 选择类:每次从待排序的无序序列中,选择一个最大或最小的数字,放到前面,数据元素为空时排序结束 1.

  • C语言每日练习之冒泡排序

    目录 分析 代码实现 运行结果 总结 分析 冒泡排序(Bubble Sort),是一种计算机科学领域的较简单的排序算法. 冒泡排序(这里只讨论从小到大排序)可以通过二种方式实现,分别是将最小值依次移动到头部和将最大值依次移动到尾部. 代码实现 代码采用从数组头部轮询的方式: #include <stdio.h> #define INTEGER_RANGE 10 //数字范围 void bubule_sort(int *array, int len); int main() { int i =

  • C语言之快速排序算法(递归Hoare版)介绍

    废话不多说,先看代码 #define _CRT_SECURE_NO_WARNINGS 1 //快速排序算法,递归求解 #include <stdio.h> void swap(int* a, int* b) { int c = 0; c = *a; *a = *b; *b = c; } void Compare(int arr[], int one, int end) { int first = one;//最左边数组下标 int last = end;//最右边数组下标 int key =

  • C语言实现快速排序算法实例

    首先我们要对一组数据进行排序: 在数组中选一个基准数(通常为数组第一个,黄圈圈标记了): 将数组中小于基准数的数据移到基准数左边,大于基准数的移到右边,怎么移动,后面说: 对于基准数左.右两边的数组,不断重复以上两个过程,直到每个子集只有一个元素,即为全部有序. 好了,咱们开始吧! 快速排序需要两个哨兵,i 和 j,分别指向数组的头和尾.接下来就要进行移动. 我们通常选择第一个元素作为基准数,去移动数组元素,使其达到这个基准数的左边都是小于它的,右边都是大于它的.开始移动 i 和 j , i 和

  • C语言之快速排序算法(递归Hoare版)介绍

    废话不多说,先看代码 #define _CRT_SECURE_NO_WARNINGS 1 //快速排序算法,递归求解 #include <stdio.h> void swap(int* a, int* b) { int c = 0; c = *a; *a = *b; *b = c; } void Compare(int arr[], int one, int end) { int first = one;//最左边数组下标 int last = end;//最右边数组下标 int key =

  • C语言实现快速排序算法

    一.快速排序算法(Quicksort) 1. 定义 快速排序由C. A. R. Hoare在1962年提出.快速排序是对冒泡排序的一种改进,采用了一种分治的策略. 2. 基本思想 通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列. 3. 步骤 a. 先从数列中取出一个数作为基准数. b. 分区过程,将比这个数大的数全放到它的右边,小于或等于它的数全

  • Go语言展现快速排序算法全过程的思路及代码示例

    快速排序算法 快速排序是一个递归的思想,首先选择一个数作为基数,把数组中小于它的数放在它的左边,把大于它的数放在它的右边,然后对左右两边的数递归进行排序. 算法的关键部分是实现数组的划分,即怎么把数组的元素划分成两部分,使得左边的数比基数小,右边的数比基数大.划分有许多不同的实现方法,这里主要使用单向扫描的方法,后面再稍微介绍双向扫描的方法. 选择最右边的数字作为基数.使用一个变量j记录当前左边数字(比基数小的数)的最右的下标值.然后使用变量i从左到右遍历数组,如果a[i]比基数小,说明a[i]

  • 逐步讲解快速排序算法及C#版的实现示例

    算法思想 快速排序是C.R.A.Hoare于1962年提出的一种划分交换排序.它采用了一种分治的策略,通常称其为分治法(Divide-and-ConquerMethod). 该方法的基本思想是: 1.先从数列中取出一个数作为基准数. 2.分区过程,将比这个数大的数全放到它的右边,小于或等于它的数全放到它的左边. 3.再对左右区间重复第二步,直到各区间只有一个数. 虽然快速排序称为分治法,但分治法这三个字显然无法很好的概括快速排序的全部步骤.因此我的对快速排序作了进一步的说明:挖坑填数+分治法:

  • C语言实现单链表的快速排序算法

    目录 背景 设计思路 算法主要步骤 快速排序算法实现 整个程序源代码 测试案例 总结 背景 传统QuickSort算法最大不足之处在于,由于其基于可索引存储结构设计(一般为数组或索引表),因而无法用于链式存储结构,而链式存储结构的实际应用非常广泛,例如动态存储管理.动态优先级调度等等,故本文针对于单向链表,以QuickSort的分治策略为基础,提出一种可用于单向链表的快速排序算法. 设计思路 将单向链表的首节点作为枢轴节点,然后从单向链表首部的第二个节点开始,逐一遍历所有后续节点,并将这些已遍历

  • C语言中使用快速排序算法对元素排序的实例详解

    调用C语言的快速排序算法qsort(); #include<stdio.h> #include<stdlib.h> #include<string.h> #define SIZE 100 //从小到大排序 int comp1(const void *x,const void *y) { return *(int *)x - *(int *)y; } //从大到小排序 int comp2(const void *x,const void *y) { return *(in

  • Java实现快速排序算法的完整示例

    首先,来看一下,快速排序的实现的动态图: 快速排序介绍: 快速排序,根据教科书说法来看,是冒泡排序的一种改进. 快速排序,由一个待排序的数组(array),以及找准三个变量: 中枢值(pivot) 左值(left) 右值(right) 根据中枢值(pivot)来做调整,将数组(array)分为三个部分: 第一部分:中枢值(pivot),单独数字构成,这个值在每次排序好的"最中间": 第二部分:左边数组(由array的一部分组成),这个数组在第一部分 中枢值(pivot) 的"

  • Python语言实现SIFT算法

    目录 一.什么是SIFT算法 二.准备工作 2.1 实验设备 2.2 OpenCV安装 三.实验工作 3.1 图像选择 3.2 程序实现 3.3 程序结果 本文侧重于如何使用Python语言实现SIFT算法 所有程序已打包:基于OpenCV-Python的SIFT算法的实现 一.什么是SIFT算法   SIFT,即尺度不变特征变换(Scale-invariant feature transform,SIFT),是用于图像处理领域的一种描述.这种描述具有尺度不变性,可在图像中检测出关键点,是一种局

随机推荐