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 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> 快速排序算法分析与Java实现 -> 正文阅读

[数据结构与算法]快速排序算法分析与Java实现

算法思想

快速排序基于分治法

  • 在待排序列L[1…n]中任取一个元素为基准,
  • 通过依然排序将待排序表划分为独立的两部分L[1…k-1]和L[k+1…n],
  • 使得L[1…k-1]中的所有元素小于pivot,L[k+1…n]中的所有元素大于或等于pivot,则pivot被放在了最终的位置上。
  • 然后递归地对两个子表重复上述过程,直到每部分只有一个元素或空为止,即所有的元素都放到了最终位置上。

结合例子对算法分析

以数组{7, 1, 2, 10, 6, 4, 3, 5, 9, 8}为例子分析算法执行的流程

  • 第一步
    初始化low,high指针
    初始化pivot为数组的第一个元素
    high指针往左移动,找到第一个小于pivot的元素
    在这里插入图片描述

  • 第二步
    将第一个小于pivot的元素放到low指针指向的位置
    在这里插入图片描述

  • 第三步
    low指针开始往右侧移动,寻找第一个大于pivot的元素
    在这里插入图片描述

  • 第四步
    将找到的第一个大于pivot的元素移动到high指针指向的位置
    在这里插入图片描述

  • 第五步
    high指针往左移动,找到第一个小于pivot的元素
    在这里插入图片描述

  • 第六步
    将找到的第一个小于pivot的元素移动到low指针指向的位置
    在这里插入图片描述

  • 第七步
    low指针往右侧移动, 寻找第一个大于pivot的元素
    此时已经不存在了, 因此low指针移动到high指针的位置就结束了寻找的循环了。
    在这里插入图片描述
    最后将pivot放在low指针(也是high指针)所在的位置,pivot这个元素就被放在最终的位置上了。
    pivot左边的元素都小于它,右边的元素都大于它。
    之后再对两个子表分别递归地进行快速排序就可以了。
    在这里插入图片描述

总结

根据我对上述的例子的观察,快速排序的关键在于选定后pivot对元素的移动。
整体来说以
high指针往左侧移动,将碰到的第一个小于pivot的元素放到low指针位置;
low指针往右侧移动,将碰到的第一个大于pivot的元素放到high指针位置;
这样两个循环为一个单位操作。
多个这样的单位操作后就会出现low指针与high指针重合的情况,此时就可以将pivot放到low指针位置,即将pivot代表的元素放到了最终的位置上了。

快速排序的空间复杂度分析

因为使用了递归,所以存在递归工作栈。
最好的情况下栈的深度为 ? l o g 2 ( n + 1 ) ? \lceil log_2(n+1)\rceil ?log2?(n+1)?,最坏情况下要进行n-1次递归调用,栈的深度为O(n)
因此空间复杂度最坏是O(n),最好是O( l o g 2 n log_2n log2?n)

快速排序的时间复杂度分析

时间效率与划分是否对称有关,最坏情况是两个区域分别包含n-1个元素和0个元素,对应于待排序表基本有序或者逆序的情况。
最坏情况下时间复杂度O( n 2 n^2 n2)

最理想的划分下,两个区域差不多大,单个不可能大于n/2
此时时间复杂度为O(n l o g 2 n log_2n log2?n)

快速排序算法平均情况下的效率与最好情况下的效率接近,因此它是所有内部排序算法中平均性能最优的排序算法。

Java代码实现

/**
* 快速排序
* 时间复杂度:pivot划分最平衡时最好O(nlog2n), 序列基本有序或者逆序时最坏O(n^2)
* 空间复杂度最好时O(log2n), 最坏时O(n)
* */
public static String quickSort(int[] originalData){
	quickSortProcess(originalData, 0, originalData.length-1);
	return Arrays.toString(originalData);
}

/**
* 快速排序的主流程
* */
public static void quickSortProcess(int[] data, int low, int high){
	//序列只有一个元素或空是递归的结束条件
	if(low < high){
		//选取pivot并且使得左侧小于pivot,右侧大于pivot
	    int pivot = quickSort_Partition(data, low, high);
	    quickSortProcess(data, low, pivot-1);//让左侧子表有序
	    quickSortProcess(data, pivot+1, high);//让右侧子表有序
	}
}

/**
* 快速排序选取基准的方法
* @return 基准pivot所在的位置
* */
public static int quickSort_Partition(int[] data, int low, int high){
	int pivot = data[low];
	while(low < high){
    	//high向左移动,找到第一个小于pivot的元素
		while(low < high && data[high] >= pivot){
			high--;
		}
    	//将第一个小于pivot的元素放到low位置
		data[low] = data[high];
    	//low向右移动,找到第一个大于pivot的元素
		while(low < high && data[low] <= pivot){
			low++;
		}
    	//将第一个大于pivot的元素放到high位置
		data[high] = data[low];
	}
	//此时low与high相等,将pivot放到这个位置即可
	data[low] = pivot;
	return low;
}
  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2022-03-04 15:50:05  更:2022-03-04 15:50:45 
 
开发: 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年11日历 -2024/11/26 16:43:20-

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