淺談快速排序的二三應用


 

大家都知道快排算法,快速排序算法的應用是非常廣泛的,這里舉出幾個例子,談一談快速排序算法的應用。快速排序的思想不僅用於單純的排序問題,對於很多查找類問題,快排算法能達到最小的時間復雜度,是最優解法之一。

首先先java實現一個快速排序函數:

 1     private int partition(int[] arr, int l, int h){
 2         int p = arr[l];
 3         int i=l; int j = h+1;
 4         while(true){
 5             while(i!=h && arr[++i]<p);
 6             while(j!=l && arr[--j]>p);
 7             
 8             if(i >= j){
 9                 swap(arr, i, j);
10                 break;
11             }
12         }
13         swap(arr, l, j);
14         return j;
15     }

1. 求一個數組里面最小的k個數

通過調用快速排序的 partition() 方法,會返回一個整數 j ,要讓得 a[l..j-1] 小於等於 a[j],且 a[j+1..h] 大於等於 a[j],此時 a[j] 就是數組的第 j 大元素。可以利用這個特性找出數組的第 K 個元素,這種找第 K 個元素的算法稱為快速選擇算法。這種算法時間復雜度為O(N) + O(1)。使用最小堆求解的話時間復雜度不變。代碼如下:

 1     public List<Integer> GetLeastNumbers(int[] nums, int k){
 2         List<Integer> ret = new ArrayList<>();
 3         if(nums.length == 0 || k>nums.length || k<0)
 4         return new ArrayList<Integer>();
 5         
 6         findKthSmallest(nums, k-1);
 7         
 8         for (int i = 0; i < k; i++)
 9             ret.add(nums[i]);
10         return ret;
11     }
12     
13     private void findKthSmallest(int[] nums, int k) {
14         int l = 0;
15         int h = nums.length-1;
16         
17         while(l<h){
18         int res = partition(nums, l, h);
19         
20         if(res == k){
21             return;
22             
23         }else if(res<k){
24             l= res+1;
25         }else{
26             h=res-1;
27         }
28         }        
29     }
30 
31     private int partition(int[] arr, int l, int h){
32         int p = arr[l];
33         int i=l; int j = h+1;
34         while(true){
35             while(i!=h && arr[++i]<p);
36             while(j!=l && arr[--j]>p);
37             
38             if(i >= j){
39                 swap(arr, i, j);
40                 break;
41             }
42         }
43         swap(arr, l, j);
44         return j;
45     }
46 
47     private void swap(int[] arr, int i, int j) {
48         int temp = arr[i];
49         arr[i] = arr[j];
50         arr[j] = temp;
51         
52     }

2 求數組中出現次數超過一半的數

容易理解次數超過一半的那個數必然是這個數組的中位數,依次可以使用快排來尋找數組的中位數,時間復雜度為O(n),java代碼如下所示

 1     public int MoreThanHalfNum(int[] nums){
 2 
 3         if(nums.length == 0 || nums == null)
 4         return 0;
 5         
 6         int ret = 0;
 7         int end = nums.length-1;
 8         int start = 0;
 9         int middle =  end/2;
10         
11         int index = partition(nums, start, end);
12         
13         while(index != middle){
14             if(index < middle) index=partition(nums, index+1, end);
15             if(index > middle) index=partition(nums, start, index-1);
16         }
17         
18         ret = nums[middle];
19      
20         return ret;
21     }
22 
23     private int partition(int[] arr, int l, int h){
24         int p = arr[l];
25         int i=l; int j = h+1;
26         while(true){
27             while(i!=h && arr[++i]<p);
28             while(j!=l && arr[--j]>p);
29             
30             if(i >= j)
31                 break;
32             
33             swap(arr, i, j);
34             
35         }
36         swap(arr, l, j);
37         return j;
38     }
39 
40     private void swap(int[] arr, int i, int j) {
41         int temp = arr[i];
42         arr[i] = arr[j];
43         arr[j] = temp;
44         
45     }

 

 時間復雜度為o(n)。

 


免責聲明!

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



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