IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> 排序算法 ---- 快速排序 -> 正文阅读

[数据结构与算法]排序算法 ---- 快速排序


一、快排简介

快速排序借助了分治的思想,它的基本思想是:

  1. 选定一个关键字 key ,通过一次排序,将其放到整个序列排序完毕的位置,并且他的左序列小于等于 key。
    右序列大于等于 key 。

  2. 递归地将分割出的两个子序列继续进行第一步排序。


图示
在这里插入图片描述




二、部分排序


1. Hoare法

默认选定 left 为keyi。 从右边找一个比key小的元素,左边找一个比key大的元素,交换两元素。当 left == right 相等。此时它们所在位置就为key最终排序所在位置。 交换 key 和 left。

注意点

关键字选 left 。得让right先找。这样才能保证正确。如果关键字选 right ,反之。


代码示例

int PartSort1(int* arr, int left, int right)
{
	int keyi = left;

	while (left < right)
	{
		while (left < right && arr[right] >= arr[keyi])
			right--;
		while (left < right && arr[left] <= arr[keyi])
			left++;
		Swap(&arr[left], &arr[right]);
	}
	Swap(&arr[keyi], &arr[left]);
	return left;
}



2.hole法


hoare法的变形,关键字 key 为 left 假定 left 为坑,从右边找一个比key小的填入坑,此时被填入的数的位置形成新的坑,再从右边找一个比key大的数填入新坑,循环往复,当 left == rihgt 此时坑所在位置就为 key 排序后位置。将key填入。

代码示例

int PartSort2(int* arr, int left, int right)
{
	int hole = left;
	int key = arr[hole];

	while (left < right)
	{
		while (left < right && arr[right] >= key)
			right--;

		arr[hole] = arr[right];
		hole = right;

		while (left < right && arr[left] <= key)
			left++;

		arr[hole] = arr[left];
		hole = left;
	}

	arr[hole] = key;
	return hole;
}



3. 双指针法

  1. prev指向下标为0元素, cur 指向下标为1元素。
  2. cur往后走,如果 arr[cur] 小于 key ,prev++,并交换prev 和 cur 所在元素。
  3. 迭代结束,prev所在位置为key最终位置。

代码示例

int PartSort3(int* arr, int left, int right)
{
	int cur = 1, prev = 0;
	int keyi = left;

	while (cur <= right)
	{
		if (arr[cur] <= arr[keyi] && ++prev != cur)
			Swap(&arr[cur], &arr[prev]);
		++cur;
	}

	Swap(&arr[prev], &arr[keyi]);
	return prev;
}



三、递归实现

当left >= right 时,说明待排区间最多只有一个元素,默认就是有序,无需排序了。

代码示例:

void QuickSort(int* arr, int left, int right)
{
	if (right <= left)
		return;

	int keyi = PartSort1(arr, left, right);

	QuickSort(arr, left, keyi - 1);
	QuickSort(arr, keyi + 1, right);
}

运行截图:
在这里插入图片描述




四、排序优化


前面我们key的选择一直为待排序列最左边数。但在待排序列有序或接近有序的情况下效率会变得非常低下。


问题示例:

当数组有序时,此时平均复杂为O(N^2) ,进行一万个数排序栈就溢出了。

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述



当待排数组内为随机数时,效率又恢复到了O(N * logN) 。十万个数也很快的排序完成。在这里插入图片描述



解决方法:

  1. 取随机数。

  2. 三数取中法 ,在left right mid 三个下标指向的数中取中位数。

代码示例:

int PartSort1(int* arr, int left, int right)
{
	//三位取中 当待排序列有序的时候也有效
	int mid = GetMid(arr, left, right);
	Swap(&arr[left], &arr[mid]);
	int keyi = left;

	while (left < right)
	{
		while (left < right && arr[right] >= arr[keyi])
			right--;
		while (left < right && arr[left] <= arr[keyi])
			left++;
		Swap(&arr[left], &arr[right]);
	}
	Swap(&arr[keyi], &arr[left]);
	return left;
}

此时十万个有序序列进行排序也可以保证效率。
在这里插入图片描述

.

  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2021-09-23 11:42:30  更:2021-09-23 11:43:52 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/17 12:11:09-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码