分享一下經常使用排序算法,給各位官人溫故而.....算法
經常使用排序算法共有6種:shell
交換算法:冒泡算法、快速排序算法;數組
選擇算法:選擇排序算法,堆排序算法;bash
插入算法:插入算法,shell排序算法。ui
冒泡排序算法:主要從頭(或從尾)依次比較相鄰兩個算法,通過一次多倫的比較交換,最小的值會優先排好。spa
static void bubbleSort(int[] data){
int temp;
for (int i = 1; i < data.length; i++) {
for (int j = 0; j < data.length-i; j++) {
if (data[j]>data[j+1]) {
temp=data[j+1];
data[j+1]=data[j];
data[j]=temp;
}
}
System.out.print(i+"次排序:");
for (int j = 0; j < data.length; j++) {
System.out.print(" "+data[j]);
}
System.out.println("\n");
}
}
複製代碼
假設輸入的值是:118,101,105,127,112。那麼打印結果以下:3d
1次排序: 101 105 118 112 127
2次排序: 101 105 112 118 127
3次排序: 101 105 112 118 127
4次排序: 101 105 112 118 127
複製代碼
快速排序算法:取一個值(一般爲數組第一個元素或中間的元素)做爲分界值。從數組右側(尾部)依次取出元素與中間值比較,直到有小於分界值的元素i,而後從左側開始,依次取出元素與中間值比較,直到有大於中間值的元素j,交換元素i和j的位置。但元素j的位置小於元素i的位置時,以元素j的位置爲分界處重複上述操做(遞歸);code
算法實現:cdn
static void quickSort(int[] data,int begin,int end){
int left=begin,right=end;
int temp=data[(right+left)/2],value;
while (left<right) {
while (data[right]>temp) {
right--;
}
while (data[left]<temp) {
left++;
}
if (left<=right) {
value=data[left];
data[left]=data[right];
data[right]=value;
right--;
left++;
}
for (int i = 0; i < data.length; i++) {
System.out.print(" "+data[i] );
}
System.out.println("");
if (left==right) {
left++;
}
if (begin<right) {
quickSort(data,begin,left-1);
}
if (left<end) {
quickSort(data, right+1, end);
}
}
}
複製代碼
假設數組元素爲:118,101,105,127,112。那麼打印結果以下:blog
105 101 118 127 112
101 105 118 127 112
101 105 118 112 127
101 105 112 118 127
複製代碼
選擇排序主要思想是遍歷數組,選擇數組中最小的元素放在第一個位置,第二小放在第二個位置,依次類推。
下面是算法的實現:
static void selectSort(int[] data) {
int temp; //用於交換數據的臨時變量
for (int i = 0; i < data.length - 1; i++) {
//從i+1位置開始,與i的位置比較
for (int j = i + 1; j < data.length; j++) {
//若是j的位置元素小於i的值,則與i位置的元素交換
//這樣就保持了i位置相對於後面的元素都是最小的
if (data[i] > data[j]) {
temp = data[i];
data[i] = data[j];
data[j] = temp;
}
}
//將每次排序後的元素打印出來,方便查看
System.out.print(i+": ");
for (int j = 0; j < data.length; j++) {
System.out.print(" "+data[j]);
}
System.out.println();
}
}
複製代碼
假如排序的數據爲:118,101,105,127,112。那麼打印出來的結果以下所示:
0: 101 118 105 127 112
1: 101 105 118 127 112
2: 101 105 112 127 118
3: 101 105 112 118 127
複製代碼
堆排序相對於選擇排序來講,比較複雜,主要是堆的構造過程(大根堆和小更堆)。而後選擇堆的根節點與最後一個葉節點交換,並輸出交換後最後一個葉節點(再也不參與後面的堆構造過程)。從新構造堆得反覆過程。
堆結構:堆結構是一種樹結構,準備說法是徹底二叉樹,由於涉及到徹底二叉樹的一些特性,假設樹有n個節點,第m個節點具備以下特性:
大根堆:若是按照從小到大的順序排序,要求非葉節點的數據要大於或等於左右子樹。
小根堆:若是按照從到到小的順序排序,要求非葉節點的數據要小於或等於子樹。
算法實現:
static void headSort(int[] data,int n){
int i,j,h,k;
int temp;
//將數組構建成大根堆
for (i=n/2-1;i>=0;i--) {
while (2*i+1<n) { //第i個元素有右子樹(意味着也有左子樹)
j=2*i+1; //左子樹下標
if (data[j]<data[j+1]) { //左子樹小於右子樹
j++; //j指向右子樹
}
//i元素與左右子樹最大值進行比較,構造大根堆
if (data[i]<data[j]) {
temp=data[i];
data[i]=data[j];
data[j]=temp;
i=j;//交換會致使子樹堆結構被破壞,須要從新構造
}else {
break;//子樹堆未被破壞
}
}
}
System.out.print("原始數據構形成的堆:");
for (int l = 0; l < data.length; l++) {
System.out.print(" "+data[l]);
}
System.out.println();
for(i=n-1;i>0;i--){
//堆得根第一個元素(數值最大)與最後一個元素(i元素,數值最小)交換
temp=data[0];
data[0]=data[i];
data[i]=temp;
k=0;
//每一步排序後須要從新構造堆,算法與上面構造初始堆是一致的
while (2*k+1<i) {
j=2*k+1;
if (data[j+1]<i) {
j++;
}
if (data[k]<data[j]) {
temp=data[k];
data[k]=data[j];
data[j]=temp;
k=j;
}else {
break;
}
}
System.out.print("第"+(n-i)+"次排序結果:");
for (int l = 0; l < data.length; l++) {
System.out.print(" "+data[l]);
}
System.out.println();
}
}
複製代碼
假如排序的數據爲:118,101,105,127,112。那麼打印出來的結果以下所示:
原始數據構形成的堆: 127 118 105 101 112
第1次排序結果: 118 112 105 101 127
第2次排序結果: 112 101 105 118 127
第3次排序結果: 105 101 112 118 127
第4次排序結果: 101 105 112 118 127
複製代碼
歸爲選擇排序算法估計就是每次挑堆中最大(或最小)的元素輸出。
插入排序主要是後面元素與前面排序好的元素比較,而後插入到合適的位置。
算法實現:
static void insetSort(int[] data){
int temp;
for (int i = 1; i < data.length; i++) {
temp=data[i];//保存i元素,下面元素後移會覆蓋數組i下標的值
int j=i-1;
while(j>=0&&temp<data[j]){//i元素與依次與前面比較,直到大於前面元素爲止
data[j+1]=data[j];//前面元素後移,方便i元素插入
j--;
}
data[j+1]=temp;
System.out.print("第"+i+"次排序結果:");
for (int l = 0; l < data.length; l++) {
System.out.print(" "+data[l]);
}
System.out.println();
}
}
複製代碼
假如排序的數據爲:118,101,105,127,112。那麼打印出來的結果以下所示:
第1次排序結果: 101 118 105 127 112
第2次排序結果: 101 105 118 127 112
第3次排序結果: 101 105 118 127 112
第4次排序結果: 101 105 112 118 127
複製代碼
主要是將有n個元素的數組分紅n/2個數字序列,第1個數據和第n/2+1數據組成一對,一對數據進行比較,後者大則調換位置進行排序。而後n/4,n/8..重複排序,直到最後n/(2*k)=1,進行插入排序算法進行排序。Shell排序比較適合數組元素比較多狀況。
算法實現:
static void shellSort(int[] data){
int x=0;
int temp;
for (int n = data.length/2; n >=1; n/=2) {//解決序列問題,即分組
int j;
for (int i = n; i < data.length; i++) {
temp=data[i];
j=i-n;//j座標所在元素與i座標所在元素成對
while (j>=0&&temp<data[j]) {
data[j+n]=data[j];
j-=n;
}
data[j+n]=temp;
System.out.print("第"+(x++)+"次排序結果:");
for (int l = 0; l < data.length; l++) {
System.out.print(" "+data[l]);
}
System.out.println();
}
}
}
}
複製代碼
這裏特地將打印信息,放到第一個循環內,能夠清楚看出序列排序。假設屬於數組爲:118,121,105,127,112,30。 則打印結果以下:
//由於共分紅6/2=3對序列,因此下標三、0,四、1,五、2一塊兒組成3對序列,進行比較交換
//105-127
第0次排序結果: 118 121 105 127 112 30
//121-112
第1次排序結果: 118 112 105 127 121 30
//102-30
第2次排序結果: 118 112 30 127 121 105
//此時。6/4=1對序列,採用插入排序算法
第3次排序結果: 112 118 30 127 121 105
第4次排序結果: 30 112 118 127 121 105
第5次排序結果: 30 112 118 127 121 105
第6次排序結果: 30 112 118 121 127 105
第7次排序結果: 30 105 112 118 121 127
複製代碼
本文參考《Java經常使用算法手冊》