快速排序的遞歸和非遞歸


快速排序,顧名思義,是一種速度快,效率高的排序算法。

  • 快排原理:
        在要排的數(比如數組A)中選擇一個中心值key(比如A[0]),通過一趟排序將數組A分成兩部分,其中以key為中心,key右邊都比key大,key左邊的都key小,然后對這兩部分分別重復這個過程,直到整個有序。
        整個快排的過程就簡化為了一趟排序的過程,然后遞歸調用就行了。
        一趟排序的方法:

  1定義i=0,j=A.lenght-1,i為第一個數的下標,j為最后一個數下標

  2從數組的最后一個數Aj從右往左找,找到第一小於key的數,記為Aj;

  3從數組的第一個數Ai 從左往右找,找到第一個大於key的數,記為Ai;

  4交換Ai 和Aj 

  5重復這個過程,直到 i=j
  6調整key的位置,把A[i] 和key交換
 
假設要排的數組為:A[8] ={ 5 2 8 9 2 3 4 9 }:
 
           選擇 key = 5, 開始時 i=0,j=7
  index       0    1    2    3    4    5    6    7
 
開始:       5    2    8    9    2    3    4    9
                  i                                         j  
第一次找   5    2    8    9    2    3    4    9
                              i                       j
交換:       5    2    4    9    2    3    8    9 
                              i                       j
第二次找   5    2    4    9    2    3    8    9
                                    i           j
交換:       5    2    4    3    2    9    8    9
                                    i            j
第三次找    5    2    4    3    2    9    8    9
                                          ij   
調整key: 2    5    4    3    5    9    8    9
                                           ij
 

--------------------- 本文來自 Yexiaofen 的CSDN 博客 ,全文地址請點擊:https://blog.csdn.net/Yexiaofen/article/details/78018204?utm_source=copy 

遞歸:

public static void sort(int a[], int low, int hight) {
int i, j, index;
if (low > hight) {
return;
}
i = low;
j = hight;
index = a[i]; // 用子表的第一個記錄做基准
while (i < j) { // 從表的兩端交替向中間掃描
while (i < j && a[j] >= index)
j--;
if (i < j)
a[i++] = a[j];// 用比基准小的記錄替換低位記錄
while (i < j && a[i] < index)
i++;
if (i < j) // 用比基准大的記錄替換高位記錄
a[j--] = a[i];
}
a[i] = index;// 將基准數值替換回 a[i]
sort(a, low, i - 1); // 對低子表進行遞歸排序
sort(a, i + 1, hight); // 對高子表進行遞歸排序

}
---------------------
作者:jianyuerensheng
來源:CSDN
原文:https://blog.csdn.net/jianyuerensheng/article/details/51258374
版權聲明:本文為博主原創文章,轉載請附上博文鏈接!

 

非遞歸:

 1 package 劍指offer.快速排序;
 2 
 3 import java.util.Stack;
 4 
 5 /**
 6  * Created by nick on 2018/10/6.
 7  * 非遞歸
 8  */
 9 public class Solution {
10     public static void main(String[] args) {
11         int[] m={5,3,6,3,2,9};
12         new Solution1().QiockSortNor(m,0,5);
13         for(int t:m)
14             System.out.println(t);
15     }
16     //一趟快速排序
17     int sort(int m[],int i,int j){
18         int x=m[i];
19             while (i<j) {//一次不行,進行多次
20                 while (i < j && m[j] >= x)//從右向左,找比x小的
21                     j--;
22                 if (i < j) {
23                     m[i] = m[j];
24                     i++;
25                 }
26                 while (i < j && m[i] <= x)//從左向右,找比x大的
27                     i++;
28                 if (i < j) {
29                     m[j] = m[i];
30                     j--;
31                 }
32                 m[i] = x;
33             }
34         return i;
35     }
36     void QiockSortNor(int num[],int low,int high)
37     {
38         Stack<Integer> st=new Stack<Integer>();
39         if(low<high)
40         {
41             int mid =sort(num,low,high);
42             if(low<mid-1){//找到中間的數之后,左右邊界入棧
43                 st.push(low);
44                 st.push(mid-1);
45             }
46             if(mid+1<high){
47                 st.push(mid+1);
48                 st.push(high);
49             }
50             while(!st.empty()){//將左右邊界出棧之后進行下一次排序操作,直到所有的元素全部出棧,沒有還在棧里面的元素
51                 int q=st.pop();//右邊界
52                 int p=st.pop();//左邊界
53                 mid=sort(num,p,q);
54                 if(p<mid-1)
55                 {
56                     st.push(p);
57                     st.push(mid-1);
58                 }
59                 if(mid+1<q)
60                 {
61                     st.push(mid+1);
62                     st.push(q);
63                 }
64             }
65         }
66     }
67 
68 }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM