排序算法:快速排序(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)算法的更多相关文章

  1. 双基准快速排序(Dual-Pivot Quicksort)(转)

    课本上常见的快速排序都是选择一个枢纽元(Pivot),基于这个枢纽元从前后双向扫描分成大于枢纽元和小于枢纽元的.而从JDK 7开始,java.util.Arrays.sort()使用双基准快速排序(D ...

  2. 快速排序改进——3区快速排序(3-way quicksort)

    1.快速排序缺陷 快速排序面对重复的元素时的处理方法是,把它放在了左部分数组或右部分数组,下次进行分区时,还需检测它.如果需要排序的数组含有大量重复元素,则这个问题会造成性能浪费. 解决方法:新增一个 ...

  3. 快速排序及STL中的sort算法

    快速排序基本思想是,对待排序序列进行划分(Partition),一次划分,选择一个元素作为枢轴,然后将所有比枢轴小的元素放到枢轴的左边,将比枢轴大的元素放到枢轴的右边.然后对该枢轴划分的左右子序列分别 ...

  4. 普林斯顿大学算法课 Algorithm Part I Week 3 快速排序 Quicksort

    发明者:Sir Charles Antony Richard Hoare 基本思想: 先对数据进行洗牌(Shuffle the array) 以数据a[j]为中心进行分区(Partition),使得a ...

  5. 现有一个接口DataOperation定义了排序方法sort(int[])和查找方法search(int[],int),已知类QuickSort的quickSort(int[])方法实现了快速排序算法

    欢迎大家加入我的社区:http://t.csdn.cn/Q52km 社区中不定时发红包 文章目录 1.UML类图 2.源码: 3.优缺点分析 1.UML类图 2.源码: package com.bac ...

  6. 算法与数据结构(十六) 快速排序(Swift 3.0版)

    上篇博客我们主要聊了比较高效的归并排序算法,本篇博客我们就来介绍另一种高效的排序算法:快速排序.快速排序的思想与归并排序类似,都是采用分而治之的方式进行排序的.快速排序的思想主要是取出无序序列中第一个 ...

  7. 快速排序算法 java 实现

    快速排序算法 java 实现 快速排序算法Java实现 白话经典算法系列之六 快速排序 快速搞定 各种排序算法的分析及java实现 算法概念 快速排序是C.R.A.Hoare于1962年提出的一种划分 ...

  8. python数据结构与算法——快速排序

    快速排序通过不断将数列分段,使得较小的数在左边的序列,较大的数在右边的序列,不断重复此过程实现排序效果.通过设置两个哨兵不断的找两个序列的较小数,较大数,并把左右的数据互换,实现对数据从粗到细的排序. ...

  9. Hark的数据结构与算法练习之快速排序

    前言 快速排序是最常见,也是面试中最容易考的排序方法,这里做一下总结 算法说明 其实这里说的很清楚了:http://blog.csdn.net/morewindows/article/details/ ...

随机推荐

  1. 更新常用的js工具函数

    在手机调试时打印代码<script src="https://cdn.bootcss.com/vConsole/3.3.0/vconsole.min.js"></ ...

  2. C#代码规范整理

    命名规范制定意义 1. 方便代码的交流和维护,便于日后自己的再次阅读. 2. 不影响编码的效率,不与大众习惯冲突. 3. 使代码更美观.阅读更方便. 4. 使代码的逻辑更清晰.更易于理解. 名词解释 ...

  3. Linux —— GDB调试程序

    调试实现 在可执行文件中加入源代码的信息,比如可执行文件中第几条机器指令对应源代码的第几行,但并不是把整个源文件嵌入到可执行文件中,所以在调试时必须保证gdb能找到源文件. 生成可执行文件命令: g+ ...

  4. 服务是如何加载并运行的, Kestrel、配置与环境

    服务是如何加载并运行的, Kestrel.配置与环境 "跨平台"后的ASP.Net Core是如何接收并处理请求的呢? 它的运行和处理机制和之前有什么不同? 本章从"宏观 ...

  5. Net Core构建Angular4应用程序

    在Visual Studio 2017中使用Asp.Net Core构建Angular4应用程序   前言 Visual Studio 2017已经发布了很久了.做为集成了Asp.Net Core 1 ...

  6. 运行node提示:events.js:160 throw er; // Unhandled 'error' event

    运行node时遇到下述提示: events.js:160  throw er; // Unhandled 'error' event或者events.js:160       throw er; // ...

  7. java wait(),notify(),notifyAll()

    wait()的作用是使当前执行代码的线程进行等待,此方法是Object类的方法,该方法用来将当前线程置入“预执行队列”中,并且在wait()所带的代码处停止执行,直到接到通知或被中断位置.在调用wai ...

  8. java实现xml文件读取并保存到对象

    首先浅聊一下解析xml的四种方式: 1.DOM方式:有缺点但是这个缺点却也是他的优点.下面详细介绍: 以树形的层次结构组织节点或信息片断集合,可以获得同一个文档中的多处不同数据.使用起来简单. 优点是 ...

  9. NgStyle和NgIf控制HTML标签显示的区别

    通常web开发者会选择将元素样式属性display设为none来隐藏目标元素.采用这种方式,这些元素虽然不可见却仍然保存在DOM中,这样带来的好处是,如果元素不久就需要再次显示,组件不需要重新被初始化 ...

  10. HTTP1.1中CHUNKED编码解析(转载)

    HTTP1.1中CHUNKED编码解析 一般HTTP通信时,会使用Content-Length头信息性来通知用户代理(通常意义上是浏览器)服务器发送的文档内容长度,该头信息定义于HTTP1.0协议RF ...