快速排序算法原理
1.快速排序算法是什么?
想必大家都學過和用過冒泡排序吧!這應該是大家成為程序員道路上學的第一個算法哦,那么我們的快速排序算法其實是在冒泡排序的基礎上的一個改進,快速排序算法是利用一趟快速排序,一趟快排一般都是取第一個數作為準基數進行排序,將一串數據分成兩個部分,
?
第一部分都比準基數小,第二部分都比準基數大,如:(-------第一部分------準基數------第二部分),也就這樣以準基數分成了兩個部分,接下來這兩個部分繼續使用一趟快排(可以用遞歸的方法),以此類推,最后數據顯示是從小到大的排列順序,
?
2.一趟快速排序是什么?
?
?
我們我們先建立一組數據:
?
| 12 | 30 | 5 | 16 | 5 | 1 | 20 | 數據 |
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 下標 |
1.根據一趟快排的規則,我們先定下一個準基數,通常準基數都是數據的第一位也就是這里的數字12
?
2.然后一趟快排是先從下標6向左進行和準基數(12)的比較,比較完一個后,然后再從下標0向右進行和準基數(12)的比較。
?
3.我們進行比較的規則和操作是:從下標6向左進行和準基數(12)的比較,只要遇到的數據小于準基數(12)的時候我們就將這個數和準基數(12)進行替換,然后再執行從下標0向右進行和準基數(12)的比較
?
如:我們從下標6向左進行和準基數(12)的比較,20>12,不滿足一趟快排的規則,尋找下一位,1<12,所以我們將下標0的值和下標5的值進行替換替換后的結果為:
| 1 | 30 | 5 | 16 | 5 | 12 | 20 | 數據 |
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 下標 |
?
4.?執行完上一步之后,我們再從下標0向右進行和準基數(12)的比較,這里的規則是只要遇到的數據大于準基數(12)的時候我們就將這個數和準基數(12)進行替換,和上面一步恰恰相反
?
如:我們再從下標0向右進行和準基數(12)的比較,30>12,所以我們將下標1的值和下標5的值進行替換
| 1 | 12 | 5 | 16 | 5 | 30 | 20 | 數據 |
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 下標 |
?
5.從左到右查找和從右到左的查找,都是通過下標來查找的,只要它們兩者下標不相遇就可以一直進行排序,直到相遇后第一次一趟快排結束,不過,總有一次會相遇的。好啦,執行完上一步之后,基本的套路也就生成了,你們可以試一下繼續執行3,4步驟吧!
?
5.?第一次一趟快排結束顯示結果為:
| 1 | 5 | 5 | 12 | 16 | 30 | 20 | 數據 |
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 下標 |
?
6.?從上面第一次一趟快排結果我們可以看出從準基數那里將數據分成的兩個部分,前面那一部分,1,5,5,都比準基數要小,后面的16,30,20,則比準基數要大。但是這還不算完,我們明顯的看到排序并非從小到大。所以說我們需要把這整一條數據分成1,5,5和16,30,20這兩個條數據再次進行一趟快排(遞歸),以此類推,直到排出一條規矩的數據為止
?
最后結果為:
| 1 | 5 | 5 | 12 | 16 | 20 | 30 | 數據 |
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 下標 |
?
代碼實現如下:
?
package com.test;public class temps {public static void main(String[] args) {int[] a = {12,20,5,16,15,1,30,45,23,9,4,4};int min = 0;int max = a.length-1;sort(a, min, max);for (int i : a) {System.out.println(i);}}/** 首先需要一個數組存放所有的數據* 定一個開始位置和一個結束為止* 選擇一個數作為準基數*/public static void sort(int a[],int min,int max) {int key=a[min];//準基數int start=min; //開始位置int end =max;//結束位置while(end>start) { //循環條件是否數值交叉//從后開始往前查找while(end>start&&a[end]>=key) {//如果找到的值大于基數值,那么繼續往下找,end--end--;}//如果找到的值小于基數值,那么進行值交換if(a[end]<key) {int i=a[end];a[end]=a[start];a[start]=i;}//從前往后找while(end>start&&a[start]<=key) {//如果找到的值小于基數值,那么繼續往下找,start++start++;}//如果找到的值大于基數值,那么進行值交換if(a[start]>key) {int i=a[start];a[start]=a[end];a[end]=i;}}//這部分的數據都是小于準基數,通過遞歸在進行一趟快排if(start>min) {sort(a, min, start-1); //開始位置為第一位,結束位置為關鍵索引-1}if(end<max) {sort(a, end+1, max); //開始位置為關鍵索引+1,結束位置最后一位}}}?
運行結果:
?
?
?
?
?
?
?
?
?
總結
- 上一篇: 压缩文件时,自动添加日期
- 下一篇: kafka消息队列-笔记