快速排序和快速选择(quickSort and quickSelect)算法
排序算法:快速排序(quicksort)递归与非递归算法
TopK问题:快速选择(quickSelect)算法
import java.util.*;
import java.lang.*;
public class Demo {
// 非递归 using stack
public static void quickSortStack(int[] nums, int left, int right) {
if (left >= right) return;
Stack<Range> stack = new Stack<Range>();
stack.push( new Range(left, right) );
while( !stack.empty() ) {
Range curRange = stack.pop();
if (curRange.left < curRange.right) {
int pivotIdx = partition(nums, curRange.left, curRange.right);
stack.push( new Range(curRange.left, pivotIdx - 1) );
stack.push( new Range(pivotIdx + 1, curRange.right) );
}
}
}
// recursion quickSort
public static void quickSort(int[] nums, int left, int right) {
if (left < right) {
int pIdx = partition(nums, left, right);
quickSort(nums, left, pIdx - 1);
quickSort(nums, pIdx + 1, right);
}
}
public static int partition(int[] nums, int left, int right) {
// nums[left]~nums[retIdx - 1] <= nums[retIdx] <= nums[retIdx ~ right]
if (left == right) return left;
int pivot = nums[left]; // mark the leftmost value as the pivot. and store it.
int lp = left, rp = right;
while(lp < rp) {
while(lp < rp && nums[rp] >= pivot)
rp--;
nums[lp] = nums[rp]; //move the smaller value to left Range.
while(lp < rp && nums[lp] <= pivot)
lp++;
nums[rp] = nums[lp]; // move the bigger value to right Range.
}
nums[lp] = pivot;
return lp;
}
public static void swap(int[] nums, int i, int j) {
int tmp = nums[i];
nums[i] = nums[j];
nums[j] = tmp;
}
public static int partitionV2(int[] nums, int left, int right) {
int l = left;
int r = right + 1;
int pivot = nums[left];
while(true) {
while( l < right && nums[++l] < pivot )
if ( l == right ) break;
while( r > left && nums[--r] >= pivot )
if ( r == left ) break;
if (l >= r)
break;
swap(nums, l, r);
}
swap(nums, left, r);
return r;
}
//TopK问题
public static int findKthLargest(int[] nums, int k) {
return quickSelect(nums, k, 0, nums.length - 1);
}
//快速选择算法
public static int quickSelect(int[] nums, int k, int left, int right) {
if (left == right) return nums[left];
int index = partition(nums, left, right);
if ( index - left + 1 == k) {
return nums[index];
}
else if ( index - left + 1 > k ) {
return quickSelect(nums, k, left, index - 1);
}
else {
return quickSelect(nums, k - index + left - 1, index + 1, right);
}
}
public static void showArrays(int[] nums, String str) {
System.out.println("===" + str + "===");
showArrays(nums);
}
public static void showArrays(int[] nums) {
for (int i = 0; i < nums.length; i++)
System.out.printf(nums[i] + " ");
System.out.println();
}
public static void main(String[] args) {
int[] nums = new int[] {1,3,2,3,4,2,7,5};
// int[] nums = new int[]{3,2,3};
showArrays(nums, "origin");
//print i-th min nubmer.
for (int i = 1; i <= nums.length; i++) {
System.out.println( i + " " + findKthLargest(nums, i) );
}
quickSortStack(nums, 0, nums.length - 1);
showArrays(nums, "quickSortStack");
}
}
class Range {
public int left;
public int right;
public Range(int left, int right) {
this.left = left;
this.right = right;
}
}
快速排序和快速选择(quickSort and quickSelect)算法的更多相关文章
- 双基准快速排序(Dual-Pivot Quicksort)(转)
课本上常见的快速排序都是选择一个枢纽元(Pivot),基于这个枢纽元从前后双向扫描分成大于枢纽元和小于枢纽元的.而从JDK 7开始,java.util.Arrays.sort()使用双基准快速排序(D ...
- 快速排序改进——3区快速排序(3-way quicksort)
1.快速排序缺陷 快速排序面对重复的元素时的处理方法是,把它放在了左部分数组或右部分数组,下次进行分区时,还需检测它.如果需要排序的数组含有大量重复元素,则这个问题会造成性能浪费. 解决方法:新增一个 ...
- 快速排序及STL中的sort算法
快速排序基本思想是,对待排序序列进行划分(Partition),一次划分,选择一个元素作为枢轴,然后将所有比枢轴小的元素放到枢轴的左边,将比枢轴大的元素放到枢轴的右边.然后对该枢轴划分的左右子序列分别 ...
- 普林斯顿大学算法课 Algorithm Part I Week 3 快速排序 Quicksort
发明者:Sir Charles Antony Richard Hoare 基本思想: 先对数据进行洗牌(Shuffle the array) 以数据a[j]为中心进行分区(Partition),使得a ...
- 现有一个接口DataOperation定义了排序方法sort(int[])和查找方法search(int[],int),已知类QuickSort的quickSort(int[])方法实现了快速排序算法
欢迎大家加入我的社区:http://t.csdn.cn/Q52km 社区中不定时发红包 文章目录 1.UML类图 2.源码: 3.优缺点分析 1.UML类图 2.源码: package com.bac ...
- 算法与数据结构(十六) 快速排序(Swift 3.0版)
上篇博客我们主要聊了比较高效的归并排序算法,本篇博客我们就来介绍另一种高效的排序算法:快速排序.快速排序的思想与归并排序类似,都是采用分而治之的方式进行排序的.快速排序的思想主要是取出无序序列中第一个 ...
- 快速排序算法 java 实现
快速排序算法 java 实现 快速排序算法Java实现 白话经典算法系列之六 快速排序 快速搞定 各种排序算法的分析及java实现 算法概念 快速排序是C.R.A.Hoare于1962年提出的一种划分 ...
- python数据结构与算法——快速排序
快速排序通过不断将数列分段,使得较小的数在左边的序列,较大的数在右边的序列,不断重复此过程实现排序效果.通过设置两个哨兵不断的找两个序列的较小数,较大数,并把左右的数据互换,实现对数据从粗到细的排序. ...
- Hark的数据结构与算法练习之快速排序
前言 快速排序是最常见,也是面试中最容易考的排序方法,这里做一下总结 算法说明 其实这里说的很清楚了:http://blog.csdn.net/morewindows/article/details/ ...
随机推荐
- php根据出生日期获取年龄
/** * @param $birthday 出生年月日(1992-1-3) * @return string 年龄 */ function countage($birthday){ $year=da ...
- WEB安全字体(Web Safe Fonts)-网页设计用什么字体兼容性好?
效果:http://sandbox.runjs.cn/show/qgdljvh4 1 Arial微软公司的网页核心字体之一,最常用的sans serif字体,当字号很小时不容易阅读.但是,大写的“I” ...
- Avito Cool Challenge 2018-A. Definite Game(思维题)
time limit per test 1 second memory limit per test 256 megabytes input standard input output standar ...
- nio aio netty区别
传统io就是bio 同步阻塞 但可以采用伪同步 nio jdk1.7以前 同步非阻塞io 1.7以后 同步异步非阻塞 ...
- C#关键字:yield
yield是C#为了简化遍历操作实现的语法糖.在语句中使用 yield 关键字,表示在该关键字所在的方法.运算符或 get 访问器是迭代器.有两种形式: yield return <expres ...
- AJPFX浅析Java内存结构
1. Heap(堆):实例分配的地方,通过-Xms与-Xmx来设置2. MethodArea(方法区域):类的信息及静态变量. 对应是Permanet Generation, 通过-XX:PermSi ...
- Android 设置资源字体,屏幕截图
字体设置 将下载的资源字体放在assets中, 引用设置 edit..setTypeface(Typeface.createFromAsset(getAssets(), "字体名.ttf&q ...
- Failed to crunch file
Failed to crunch file 编译时,出现以上错误,经过多次排除验证,原因尽然是因为路径字符太长了... 编译路径不能超过240个字符
- Windows平台下如何在C#中调用Python
最近迷上了Python,发现它能够做很多C#无法完成的事情,比如,调用CMD或者在CMD中执行一个exe文件命令行并获得输出的结果.过程简单,处理起来也非常方便,但如果要用C#调用Python文件呢, ...
- python基础教程总结11——图形用户界面GUI
1. 丰富的平台 工具包 描述 Tkinter 使用Tk平台.很容易得到.半标准. wxpython 基于wxWindows.跨平台越来越流行. PythonWin 只能在Windows上使用.使用了 ...