美文网首页
快速排序

快速排序

作者: KeDaiBiaO1 | 来源:发表于2017-10-04 14:59 被阅读0次

这个是排序
还有一个二分插入

虽然最坏情况下时间复杂度为


不过平均性能比较好 ,而且是原址排序

思路:
每次先取得中间值(取A[q]为哨兵,比哨兵小的值在左边,最后一个比哨兵小的值的位置+1(pos) 和A[q]交换)
然后sort

pos是比哨兵小的值
i遍历从p到q
出现需要交换的值的时候(哨兵大于等于A[i])pos+1
pos是比哨兵小的值,pos+1是大于等于哨兵的值,
A[i]是需要交换的值。change A[i]和A[pos]
然后pos+1和哨兵的值交换。
伪代码如下:

QUICKSORT(A,p,r)
if p<r
q=DPARTITION(A,p,r)
QUICKSORT(A,p,q-1)
QUICKSORT(A,q+1,r)

PARTITION(A,p,r)
x=A[r]
i =p-1
for j=p to r-1
  if a[j]<=x
    i=i+1
    exchange a[i]? with A[j]?
exchange A[i+1] with A[r]?
return i+1

这个是算法导论中的实现方法
思路是:
选数组中最后一个元素作为基准进行划分,一次划分之后,返回一个位置(代码实现中的position字段)在这个位置之前所有的元素都比a[position]小,而在这个位置之后的元素都比这个元素大。然后用分治法把position左右两边的子问题在重新递归求解。
代码实现:

    @Test
    public void test01(){
        int[]a = { 2, 8, 7, 1, 3, 5, 6, 4 };
        sort(a, 0, a.length - 1);
        printArray(a);
    }
    public void sort(int[] a, int low, int height){
        
        if(low < height){
            int position = partition(a, low, height);
            sort(a, low, position - 1);
            sort(a, position + 1, height);
        }
    }
    public int partition(int[] a, int low, int height){
        //和这个中间值比较
        int x = a[height];
        //表示位置   需要被换的   这个位置开始比tmp大  后来被替换到后面
        int position = low - 1;
        //交换类排序
        //i不从0开始  要注意这几个不从0开始的
        for (int i = low; i < height; i++) {
            if(a[i] <= x){
                //如果小于   就和前面的position
                position ++;
//              int tmp = a[position];
//              a[position] = a[i];
//              a[i] = tmp;
                int tmp = a[position];
                a[position] = a[i];
                a[i] = tmp;
            }
        }
        //交换pos+1 和 x
        int tmp = a[position + 1];
        a[position + 1] = a[height];
        a[height] = tmp;
        return position +1;
    }
    public static void printArray(int[] array) {
        for (int i : array) {
            System.out.print(i + "");
        }
    }

从代码里面看出来快速排序是不稳定排序,属于交换排序。
分析:
主要就是partition方法
这个方法是对数组从low到height之间的元素排序并返回划分左右两边的中间位置
需要注意的几个边界:

  1. for循环不能从0开始 (因为要后面递归的不一定是从0开始的)
  2. for循环中i < height 的height 不能用数组长度 因为有一个基准去掉了。

需要理解的几个问题:

  1. 为什么需要a[i] == x的时候也交换?
    因为如果不交换,后面的比a[height] (基准)小的时候,要和前面的交换(会把和基准相等的交换到后面去)
  2. 交换基准(或者定位position)
    基准是数组的分界,左边比基准小右边 比基准大
    因为当发生a[i] <= x的时候 就会发生(记录position后移),也就是i循环完之后position位置刚好是(从左到右)最后一个比基准小的数(包括position+1的后面元素都比基准要大),所以用基准把这个位置替换并返回这个位置

相关文章

  • 七大排序算法之快速排序

    七大排序算法之快速排序 @(算法笔记)[排序算法, 快速排序, C++实现] [TOC] 快速排序的介绍: 快速排...

  • 面试准备--排序

    堆排序 快速排序(simple) 快速排序(regular) 归并排序 Shell排序 插入排序 选择排序 冒泡排序

  • 排序

    插入排序 选择排序 冒泡排序 归并排序 快速排序* 三路快速排序

  • 算法笔记01-排序#2

    快速排序敢叫快速排序,那它一定得快。 快速排序 概述 快速排序也是分治排序的典型,它快,而且是原地排序。不过,要防...

  • PHP 实现快速排序

    导语 这篇了解下快速排序。 快速排序 快速排序(英语:Quicksort),又称划分交换排序(partition-...

  • 快速排序的Python实现

    目录 快速排序的介绍 快速排序的Python实现 快速排序的介绍 快速排序(quick sort)的采用了分治的策...

  • 数据结构与算法 快速排序

    起因:快速排序,又称分区交换排序,简称快排,之前没有了解过,抽空学习一下。 快速排序 1 快速排序 快速排序的定义...

  • 数组-快速排序

    采用快速方式对数组进行排序 快速排序百科:快速排序(Quicksort)是对冒泡排序算法的一种改进.快速排序是通过...

  • OC数据结构&算法

    更多整理资料尽在?一平米小站 目录 选择排序 冒泡排序 插入排序 快速排序 双路快速排序 三路快速排序 堆排序 选...

  • 要成功就做一百题-94

    题目名称 今天来几个排序,都是经典题目,包括带拆分的快速排序,堆排序,归并排序。 描述 快速排序快速排序核心就是分...

网友评论

      本文标题:快速排序

      本文链接:https://www.haomeiwen.com/subject/qkqcyxtx.html