快速排序核心算法

这只是核心的算法,当然还存在一些优化的做法,但都是基于以下算法拓展的。 1 package com.meession.javaDataStruct.QuickSort;
 2
 3 /**
 4  * 快排算法思想:
 5  * 基于冒泡排序,对其改进,采用递归实现。    数组分区:此趟递归带排序的数组; 
 6  * 对于每一次的函数调用,
 7  * i都被设置为从该数组分区的第0个元素开始,j从该数组分区的最后一个元素开始。
 8  * (因为在QuickSort方法中,我们看到的是第一步方法递归之前的代码执行过程,
 9  * 而第一步方法递归之前的数组分区是整个被待排序的数组,
10  * 所以在第一步递归之前i从整个数组的第0个元素开始,j从整个数组的最后一个元素开始)
11  * 并设置一个参照点。(理论上可以是该数组分区里面的任何值,
12  * 但由于在递归过程中数组长度的不确定性,导致容易出现数组越界的异常出现。
13  * 因此用该数组分区的第0个元素作为整个分区的参照点,以规避数组越界的异常发生)。
14  *
15  * 在找比参照点大和比参照点小的数据的时候不让i比j先执行循环的原因是:
16  * 一开始参照点被设置在了最左边,若按循环条件去寻找比参照点大的元素,
17  * 分隔数据的目的将无法达到。
18  * ^_^只有改变循环的条件才能做到i比j先执行循环又达到分隔数据的效果^_^。
19  *
20  * 在第一次递归之前的操作和原理弄明白之后,接下来就是递归的过程。
21  * 递归可以这么理解:你所使用的这个方法是别人已经给你写好的,
22  * 你只需使用它来完成你要实现的功能即可。
23  * 比如下面的sort函数的递归,你可以理解成:sun公司已经给你写好了这个方法,
24  * 它的参数就是这些:int[] arrs,int left,int right;
25  * 你需要实现的功能是:把参照点左边的数组分区和右边的数组分区的数据有序排好即可。
26  * 但在一开始自己编写这个方法的时候肯定不能这么理解,
27  * 不然我们就真的可以直接调用sun公司写好的快排方法了。
28  * 以上辅助理解的方式只是为了不要因为递归而把自己陷进头大般的痛苦之中。
29  * 简单来说,就是这么理解:你只需完成过程前的第一步操作,
30  * 接下了的操作就是自己调用已有的方法完成。两步加在一起,整个排序就完成了。
31  * 当然,递归肯定要有结束条件,就是:当数组分区的元素只有一个时,
32  * 即数组分区的最左边等于最右边等于键值的所在位置是时,对于每一个数组分区而言,
33  * 都是有序的。整个待排序数组也就成了有序的了。
34  *
35  * ************************************************************
36  * 这只是快排的核心算法,若在某些地方改进,快排的执行效率会更高。
37  *
38  * 优点:排序的平均速度快(顾名思义嘛),计算机执行效率高
39  * 缺点:排序结果不稳定。也就是说,如果数组中存在n个大小相同的元素,
40  * 排序之后这n个元素的位置可能发生变化。即如果原来的序列是:n1、n2、n3、n4,
41  * 排序之后的序列可能变为:n2、n1、n4、n3
42  *
43  * 它的时间复杂度 最好O(NlogN),最坏O(N^2),平均O(NlogN)
44  * 空间复杂度:最好O(logN),最坏O(N),平均:O(logN)
45  * @author fzh
46  *
47  */
48 public class QuickSort {
49     public void sort(int[] arrs,int left,int right){
50         /**
51          * i从数组分区的第0个元素开始,j从数组分区的最后一个元素开始
52          * key为数组分割参照点。为防止数组越界异常出现,初始化key为数组分区的第0个元素
53          */
54         int i = left;
55         int j = right;
56         int key = arrs[left];
57         /**
58          * 用于交换数据的临时变量
59          */
60         int temp;
61         /**
62          * 循环结束条件必为:i==j
63          */
64         while(i<j){
65             /**
66              * 当扫描数组分区的下标比待分隔区间(即参照点所在的区间的子区间,
67              * 这个区间左边元素全部小于参照点,右边的元素全部大于参照点。
68              * 而在这个区间的元素和参照点的大小关系还不确定)的最左边元素的下标大
69              * 且最左边元素后面的数据比参照点大的时候,下面这个循环满足循环条件,
70              * j减一,继续执行循环去找下标比i(分隔区间的最左边数据的下标)大、
71              * 数值比参照点小的数据,然后做交换
72              */
73             while(j>i&&arrs[j]>=key)j--;
74             if(j>i){
75                 temp = arrs[j];
76                 arrs[j] = arrs[i];
77                 arrs[i] = arrs[j];
78             }
79
80             /**
81              * 当扫描数组分区的下标比待分隔区间的最左边元素的下标大
82              * 且待分隔区间的最左边元素后面的数据比参照点小的时候,下面这个循环满足循环条件,
83              * i加1,继续执行循环去找下标比j(分隔区间的最右边数据的下标)小、
84              * 数值比参照点大的数据,然后做交换
85              */
86             while(i<j&&arrs[i]<=key)i++;
87             if(i<j){
88                 temp = arrs[j];
89                 arrs[j] = arrs[i];
90                 arrs[i] = temp;
91             }
92
93         }
94         if(i>left)sort(arrs, left, i-1);
95         if(j<right)sort(arrs, j+1, right);
96     }
97 }
时间: 2024-10-07 13:33:28

快速排序核心算法的相关文章

x264代码剖析(十五):核心算法之宏块编码中的变换编码

x264代码剖析(十五):核心算法之宏块编码中的变换编码 为了进一步节省图像的传输码率,需要对图像进行压缩,通常采用变换编码及量化来消除图像中的相关性以减少图像编码的动态范围.本文主要介绍变换编码的相关内容,并给出x264中变换编码的代码分析. 1.变换编码 变换编码将图像时域信号变换成频域信号,在频域中图像信号能量大部分集中在低频区域,相对时域信号,码率有较大的下降. H.264对图像或预测残差采用4×4整数离散余弦变换技术,避免了以往标准中使用的通用8×8离散余弦变换逆变换经常出现的失配问题

Google(谷歌)矩阵是怎算的? --- 核心算法PageRank

如图为谷歌矩阵的模型: 首先这是一个四乘以四的矩阵,行从1 2 3 4  列1 2 3 4 0表示没有指向自己的连接,非零表示有指向自己的连接. 那么其中的 1/3 和 1/2是什么意思? 是这样的,表示第一列代表的是1, 第二列代表的是2 那么第一个一共有三个指向外面的箭头,那么每一个就是1/3. 这就是很经典的核心算法PageRank.

用Java实现MVPtree——MVPtree核心算法代码的搭建

项目需要,需要把MVPtree这种冷门的数据结构写入Java,然网上没有成形的Java实现,虽说C++看惯了不过对C++实现复杂结构也是看得蒙蔽,幸好客户给了个github上job什么的人用Java写的VPtree,大体结构可以嵌入MVPtree. 对于MVPtree的其他信息请左转百度= =本文只讲述算法实现. 点查找树结构主要需解决的问题有2个:如何减少非必要点的搜索,以及如何减少距离计算次数.前者的解决方法比较容易想到,把点集分割为左右对称的两半长方形,或者脑洞大点的,通过距离切分(效率很

SQL关键字转换大写核心算法实现

1 不跟你多废话 上代码! /// <summary> /// SQL关键字转换器 /// </summary> public class SqlConverter : IKeywordsConvertible { public SqlConverter(string[] keywords) { Keywords = keywords; } public SqlConverter() { } /// <summary> /// 关键字集合 /// </summar

快速排序的算法导论划分形式和hoare划分

1. hoare划分 1 int hoare_partition(int a[], int begin, int end) 2 { 3 int pivot = a[begin]; 4 int ini = begin; 5 int ter = end; 6 while (ini < ter) 7 { 8 while (a[ini] <= pivot && ini <end) 9 ++ini; 10 while (a[ter] >= pivot && t

快速排序之算法导论实现

#include <iostream> using namespace std; int partition(int *a,int p,int r) { int x=a[r]; int i=p-1;//note i important which is used for //storage the number smaller than flag x=a[r] for (int j=p;j<r;j++) { if (a[j]<x)// if a[j] smaller than x=

快速排序的算法

自学java到数组时,学习到了两种排序方法:选择排序和冒泡排序,冒泡排序是选择排序的进阶阶段,精简了运算的过程.了解到,java语言已经提供了排序的方法:通过util.Arrays.sort可以对数组进行自动排序,而排序方法用的是快速排序的一种. 快速排序是冒泡排序的进阶阶段,那么快速排序的基本原理又是什么呢.通过查阅资料,了解了算法,自己也尝试了写了一些快速排序的算法原理. 1 package array; 2 //快速排序原理 3 import java.util.Arrays; 4 pub

团队项目:核心算法实现

本游戏中最为核心的算法在于绘制轨道曲线的算法,实现如下: 每帧获取屏幕上的鼠标的位置设置为终点vt,之前上一帧设置的起点为v0,则这一帧所生成的轨道就是从v0到vt.在轨道生成完成后,将v0设置为vt,以便于下一帧继续进行轨道的生成. 流程图: 图1 核心算法流程图 伪代码: 1.检测是否按住鼠标左键,是则进入2,否则进入8. 2.获取鼠标在屏幕上的当前位置并转换为世界坐标temp_pos. 3.如果是第一次按下(first为true),将当前temp_pos赋给begin_pos,将first

x264代码剖析(十七):核心算法之熵编码(Entropy Encoding)

x264代码剖析(十七):核心算法之熵编码(Entropy Encoding) 熵编码是无损压缩编码方法,它生产的码流可以经解码无失真地恢复出原始数据.熵编码是建立在随机过程的统计特性基础上的.本文对熵编码中的CAVLC(基于上下文自适应的可变长编码)和CABAC(基于上下文的自适应二进制算术熵编码)进行简单介绍,并给出x264中熵编码对应的代码分析. 在H.264的CAVLC中,通过根据已编码句法元素的情况,动态调整编码中使用的码表,取得了极高的压缩比.CAVLC用于亮度和色度残差数据的编码,