基于JAVA的排序算法之五--快速排序

五、快速排序(Quick Sort)

1. 基本思想:

  在当前无序区R[1..H]中任取一个数据元素作为比较的"基准"(不妨记为X),用此基准将当前无序区划分为左右两个较小的无序区:R[1..I-1]和R[I+1..H],且左边的无序子区中数据元素均小于等于基准元素,右边的无序子区中数据元素均大于等于基准元素,而基准X则位于最终排序的位置上,即R[1..I-1]≤X.Key≤R[I+1..H](1≤I≤H),当R[1..I-1]和R[I+1..H]均非空时,分别对它们进行上述的划分过程,直至所有无序子区中的数据元素均已排序为止。

2. 排序过程:

【示例】:

 

初始关键字 [49 38 65 97 76 13 27 49]

一趟排序之后 [27 38 13]49 [76 97 65 49]

二趟排序之后 [13]27 [38]49 [49 65]76 [97]

三趟排序之后13 27 38 49 49 [65]76 97

最后的排序结果13 27 38 49 49 65 76 97

各趟排序之后的状态

java代码实现:

 

01.   

04.   

05.public class QuickSort {      

06.     

07.         

14.    //定义了一个这样的公有方法sort,在这个方法体里面执行私有方法quckSort(这种方式值得借鉴)。   

15.    public void sort(Integer[] array, int from, int end) {      

16.        quickSort(array, from, end);      

17.        

18.     

19.         

26.    private void quickSort(Integer[] array, int low, int high) {      

27.             

32.        if (low < high) {      

33.            //对分区进行排序整理      

34.               

35.            //int pivot = partition1(array, low, high);   

36.            int pivot = partition2(array, low, high);      

37.            //int pivot = partition3(array, low, high);         

38.               

39.                 

44.            quickSort(array, low, pivot - 1);      

45.            quickSort(array, pivot + 1, high);      

46.            

47.     

48.        

49.     

50.         

59.    private int partition1(Integer[] array, int low, int high) {      

60.        Integer pivotElem = array[low];//以第一个元素为中枢元素      

61.        //从前向后依次指向比中枢元素小的元素,刚开始时指向中枢,也是小于与大小中枢的元素的分界点      

62.        int border = low;      

63.     

64.             

69.        for (int i = low + 1; i <= high; i++) {      

70.            //如果找到一个比中枢元素小的元素      

71.            if ((array[i].compareTo(pivotElem)) < 0) {      

72.                swap(array, ++border, i);//border前移,表示有小于中枢元素的元素      

73.                

74.            

75.             

83.        swap(array, border, low);      

84.        return border;      

85.        

86.     

87.         

96.    private int partition2(Integer[] array, int low, int high) {      

97.        int pivot = low;//中枢元素位置,我们以第一个元素为中枢元素      

98.        //退出条件这里只可能是low = high      

99.        while (true) {      

100.            if (pivot != high) {//如果中枢元素在低指针位置时,我们移动高指针      

101.                //如果高指针元素小于中枢元素时,则与中枢元素交换      

102.                if ((array[high].compareTo(array[pivot])) < 0) {      

103.                    swap(array, high, pivot);      

104.                    //交换后中枢元素在高指针位置了      

105.                    pivot = high;      

106.                } else {//如果未找到小于中枢元素,则高指针前移继续找      

107.                    high--;      

108.                    

109.            } else {//否则中枢元素在高指针位置      

110.                //如果低指针元素大于中枢元素时,则与中枢元素交换      

111.                if ((array[low].compareTo(array[pivot])) > 0) {      

112.                    swap(array, low, pivot);      

113.                    //交换后中枢元素在低指针位置了      

114.                    pivot = low;      

115.                } else {//如果未找到大于中枢元素,则低指针后移继续找      

116.                    low++;      

117.                     

118.                

119.            if (low == high) {      

120.                break;      

121.                

122.            

123.        //返回中枢元素所在位置,以便下次分区      

124.        return pivot;      

125.        

126.     

127.         

136.    private int partition3(Integer[] array, int low, int high) {      

137.        int pivot = low;//中枢元素位置,我们以第一个元素为中枢元素      

138.        low++;      

139.        //----调整高低指针所指向的元素顺序,把小于中枢元素的移到前部分,大于中枢元素的移到后面部分      

140.        //退出条件这里只可能是low = high      

141.     

142.        while (true) {      

143.            //如果高指针未超出低指针      

144.            while (low < high) {      

145.                //如果低指针指向的元素大于或等于中枢元素时表示找到了,退出,注:等于时也要后移      

146.                if ((array[low].compareTo(array[pivot])) >= 0) {      

147.                    break;      

148.                } else {//如果低指针指向的元素小于中枢元素时继续找      

149.                    low++;      

150.                    

151.                

152.     

153.            while (high > low) {      

154.                //如果高指针指向的元素小于中枢元素时表示找到,退出      

155.                if ((array[high].compareTo(array[pivot])) < 0) {      

156.                    break;      

157.                } else {//如果高指针指向的元素大于中枢元素时继续找      

158.                    high--;      

159.                    

160.                

161.            //退出上面循环时low = high      

162.            if (low == high) {      

163.                break;      

164.                

165.     

166.            swap(array, low, high);      

167.            

168.     

169.        //----高低指针所指向的元素排序完成后,还得要把中枢元素放到适当的位置      

170.        if ((array[pivot].compareTo(array[low])) > 0) {      

171.            //如果退出循环时中枢元素大于了低指针或高指针元素时,中枢元素需与low元素交换      

172.            swap(array, low, pivot);      

173.            pivot = low;      

174.        } else if ((array[pivot].compareTo(array[low])) <= 0) {      

175.            swap(array, low - 1, pivot);      

176.            pivot = low - 1;      

177.            

178.     

179.        //返回中枢元素所在位置,以便下次分区      

180.        return pivot;      

181.        

182.       

183.             

189.    public void swap(Integer[] array, int i, int j) {      

190.        if (i != j) {//只有不是同一位置时才需交换      

191.            Integer tmp = array[i];      

192.            array[i] = array[j];      

193.            array[j] = tmp;      

194.            

195.      

196.       

197.         

201.    public static void main(String[] args) {      

202.        Integer[] intgArr = { 5, 9, 1, 4, 2, 6, 3, 8, 0, 7 };     

203.        QuickSort quicksort = new QuickSort();      

204.        quicksort.sort(intgArr,0,intgArr.length-1);   

205.        for(Integer intObj:intgArr){   

206.            System.out.print(intObj + " ");   

207.         

208.        

209.}      

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值