快速排序相关算法题,安卓app开发入门书籍推荐

举例来说,现有数组 arr = [3,7,8,5,2,1,9,5,4],分区可以分解成以下步骤:

首先选定一个基准元素,这里我们元素 5 为基准元素(基准元素可以任意选择):

首先选定一个基准元素,这里我们元素 5 为基准元素(基准元素可以任意选择):

pivot

3 7 8 5 2 1 9 5 4

将基准元素与数组中最后一个元素交换位置,如果选择最后一个元素为基准元素可以省略该步:

pivot

3 7 8 4 2 1 9 5 5

从左到右(除了最后的基准元素),循环移动小于基准元素 5 的所有元素到数组开头,留下大于等于基准元素的元素接在后面。在这个过程它也为基准元素找寻最后摆放的位置。循环流程如下:

循环 i == 0 时,storeIndex == 0,找到一个小于基准元素的元素 3,那么将其与 storeIndex 所在位置的元素交换位置,这里是 3 自身,交换后将 storeIndex 自增 1,storeIndex == 1:

pivot

3 7 8 4 2 1 9 5 5

storeIndex

循环 i == 3 时,storeIndex == 1,找到一个小于基准元素的元素 4:

┌───────┐ pivot

↓ ↓ ↓

3 7 8 4 2 1 9 5 5

↑ ↑

storeIndex i

交换位置后,storeIndex 自增 1,storeIndex == 2:

pivot

3 4 8 7 2 1 9 5 5

storeIndex

循环 i == 4 时,storeIndex == 2,找到一个小于基准元素的元素 2:

┌───────┐ pivot

↓ ↓ ↓

3 4 8 7 2 1 9 5 5

↑ ↑

storeIndex i

交换位置后,storeIndex 自增 1,storeIndex == 3:

pivot

3 4 2 7 8 1 9 5 5

storeIndex

循环 i == 5 时,storeIndex == 3,找到一个小于基准元素的元素 1:

┌───────┐ pivot

↓ ↓ ↓

3 4 2 7 8 1 9 5 5

↑ ↑

storeIndex i

交换后位置后,storeIndex 自增 1,storeIndex == 4:

pivot

3 4 2 1 8 7 9 5 5

storeIndex

循环 i == 7 时,storeIndex == 4,找到一个小于等于基准元素的元素 5:

java hljs    6行

┌───────────┐ pivot

↓ ↓ ↓

3 4 2 1 8 7 9 5 5

↑ ↑

storeIndex i

交换后位置后,storeIndex 自增 1,storeIndex == 5:

java hljs    6行

pivot

3 4 2 1 5 7 9 8 5

storeIndex

循环结束后交换基准元素和 storeIndex 位置的元素的位置:

pivot

3 4 2 1 5 5 9 8 7

storeIndex

那么 storeIndex 的值就是基准元素的最终位置,这样整个分区过程就完成了。

附件0.00KB

下面我们来看一下源码是怎样实现的

1. 简单来说就是先找出一个索引,左边的数都比他小,右边的数都比他大 ,接着利用递归排列左边和右边的数,直到low>=high

private static void qSort(int[] data, int low, int high) {

int pivot;

if (low < high) {

pivot = partition(data, low, high);

qSort(data, 0, pivot - 1);

qSort(data, pivot + 1, high);

}

}

2. 下面我们来看一下partition函数式怎样实现的

private static int partition(int[] data, int low, int high) {

int pivotKey;

pivotKey = data[low];

while (low < high) {

// 将小于基准点的值得数放到前面

while (low < high && data[high] >= pivotKey) {//

high–;

}

ArrayUtils.exchangeElements(data, low, high);

// 将大于基准点的值得数放到后面

while (low < high && data[low] <= pivotKey) {

low++;

}

ArrayUtils.exchangeElements(data, low, high);

}

// 返回基准点的索引

return low;

}


其实就是从两端进行扫描,发现小于基准点的 数的时候,将其放到前面到,发现大于基准点的数的时候,将其发到后面去

到此快速排序的分析为止


数组中出现次数超过一半的数字


一、问题描述

给定一个数组,数组中的数据无序,在一个数组中找出其第k个最小的数,例如对于数组x,x = {3,2,1,4,5,6},则其第2个最小的数为2。

二、解题思路

本算法跟快排的思想相似,首先在数组中选取一个数centre作为枢纽,将比centre小的数,放到centre的前面将比centre大的数,放到centre的后面。如果此时centre的位置刚好为k,则centre为第k个最小的数;如果此时centre的位置比k前,则第k个最小数一定在centre后面,递归地在其右边寻找;如果此时centre的位置比k后,则第k个最小数一定在centr
e后面,递归地在其左边寻找。

三、代码

package com.xujun.quicksort;

import java.util.Collections;

public class MinIndex {

static int[] a = new int[] { 20, 9, 3, 5, 26, 100, 8, -1, 7, 50, -5, 20, -1 };

public static void main(String[] args) {

System.out.println(“before sort”);

ArrayUtils.printArray(a);

int k=8;

int pivot = findMinIndexInArray(a, k);

System.out.println(“after sort”);

ArrayUtils.printArray(a);

System.out.println(“数组中最小的第”+k+"个数是 " + a[pivot]);

}

private static int findMinIndexInArray(int[] data, int k) {

if (data == null || data.length < k) {

return -1;

}

int start = 0;

int end = data.length - 1;

int pivot = partition(data, start, end);

while (pivot != k - 1) {

if (pivot < k - 1) {

start = pivot + 1;

pivot = partition(data, start, end);

} else {

end = pivot - 1;

pivot = partition(data, start, end);

}

}

return pivot;

}

private static int partition(int[] data, int low, int high) {

int pivotKey;

/*

  • pivotKey = data[low];// 选取low作为基准点,pivotKey为基准点的值

*/

int middle = low + (high - low) / 2;

if (data[low] > data[high]) {// 较大的数存在high中

ArrayUtils.exchangeElements(data, low, high);

}

if (data[middle] > data[high]) {

ArrayUtils.exchangeElements(data, middle, high);

}

if (data[middle] > data[low]) {

ArrayUtils.exchangeElements(data, middle, low);

}

pivotKey = data[low];// 选取low作为基准点,pivotKey为基准点的值

// 将大于基准点的值得数放到后面

while (low < high) {

while (low < high && data[high] >= pivotKey) {//

high–;

}

data[low] = data[high];

// 将小于基准点的值得数放到前面

while (low < high && data[low] <= pivotKey) {

low++;

}
) / 2;

if (data[low] > data[high]) {// 较大的数存在high中

ArrayUtils.exchangeElements(data, low, high);

}

if (data[middle] > data[high]) {

ArrayUtils.exchangeElements(data, middle, high);

}

if (data[middle] > data[low]) {

ArrayUtils.exchangeElements(data, middle, low);

}

pivotKey = data[low];// 选取low作为基准点,pivotKey为基准点的值

// 将大于基准点的值得数放到后面

while (low < high) {

while (low < high && data[high] >= pivotKey) {//

high–;

}

data[low] = data[high];

// 将小于基准点的值得数放到前面

while (low < high && data[low] <= pivotKey) {

low++;

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值