【知了堂学习笔记】java 编写几种常见排序算法3
排序的分類:
1.希爾排序
希爾排序是快速插入排序的改進版,希爾排序是把記錄按下標的一定增量分組,對每組使用直接插入排序算法排序;隨著增量逐漸減少,每組包含的關鍵詞越來越多,當增量減至1時,整個文件恰被分成一組,算法便終止
基本思路:先取一個小于n的整數d1作為第一個增量,把文件的全部記錄分組。所有距離為d1的倍數的記錄放在同一個組中。先在各組內進行直接插入排序;然后,取第二個增量d2<d1重復上述的分組和排序,直至所取的增量?=1(?<?…<d2<d1),即所有記錄放在同一組中進行直接插入排序為止,一般是選取d1為數組的一半,d2為d1的一半以此類推..
具體代碼:
package Sort;public class Shell_sort {public static void main(String[] args) {// TODO Auto-generated method stubint[] a = {78,68,48,39,95,48,94,73};//希爾排序int d=a.length;while(d>1){d=d/2;for(int x=0;x<d;x++){//以d為公差分組,分成d個數組,每個數組為{a[i+d],a[i+2d],a[i+3d]....}for(int i=x+d;i<a.length;i=i+d){//按直接插入排序將這些數組排序(具體方法查看我的直接插入排序http://www.cnblogs.com/pipixiao/p/7674142.html)int temp=a[i];int j;for(j=i-d;j>=0&&a[j]>temp;j=j-d){a[j+d]=a[j];}a[j+d]=temp;}}}System.out.println("排序之后:");for(int i=0;i<a.length;i++){System.out.print(a[i]+" ");} } }運行結果:
?
2.堆排序
大根堆排序,小根堆排序。
大根堆排序:先構建二叉樹(構建的二叉樹必須滿足父節點必須大于其左右子節點,數組中第一個數字為a【0】其左右子節點的應為a【1】,a【2】,以腳標定義既是父節點為a【i】,其左右子節點分別為a【2i+1】,a【2i+2】),再將二叉樹中第一個數獲取放入另外一個空數組中,剩下的數重新形成一個新的數組,再重新建堆,重復上述步驟,直到原數組中數字被取完,得到的新數組,既是一個由大到小排序完成的數組
由此二叉樹可知2是5,6的父節點,將2,5,6三個位置的數比較大小,得到最大的數與2位置的交換,當得到的數就是2本身,不做交換,(1,3,4),(0,1,2)位置的數也應該做同樣的步驟,這樣最終0位置獲得的數既是最大的數,然后將得到的數組中a【0】拿出,后面的數構建新數組,重新再構建樹。重復上述步驟
注意:這里可以看出構建數循環的次數為3次即:for(int i=(a.lenght-1)/2-1,i>=0,i--);但是當出現下面這種情況時很顯然這個條件不滿足,下面循環的次數為4次,我們可以不改變上述循環的原理上面加一點既:for(int i=(a.lenght-1)/2-1+(a.lenght-1)%2;i>=0;i--)其實對比不難看出當數組的長度為偶數的時候,得到的二叉樹最后悔單出來一個位置,這里面比較的條件就會發生變化,而(a.lenght-1)%2可以得到長度為偶數則加一次循環,為奇數時不變。
構建的數是這種情況的時候(3,7)位置的數比較的時候只有兩個數比較,所以這里出現了一個不同,就應該加一個判斷條件(本次比較是否存在a【2i+2】這一項,如果不存在則比較的數只有a【i】與a【2i+1】)
具體代碼:
?
package Sort;import java.util.Arrays;public class HeapSort {public static void main(String[] args) {// TODO Auto-generated method stubint[] arr = {78,68,48,39,95,48,94,73};int[] a = new int[8];for(int i=0;i<a.length;i++){heap(arr);a[i]=arr[0];//將當前數組第一個數獲取給數組aarr=Arrays.copyOfRange(arr,1,arr.length);//截取取arr數組的第一個數后面的所有數,重新給arr }for (int m = 0; m < a.length; m++) {//遍歷輸出數組a,數組a既是排序完成后的數組System.out.print(a[m]+" ");}}public static void heap(int[] arr){//創建堆int temp=0;for(int j=(arr.length-1)/2-1+(arr.length-1)%2;j>=0;j--){//獲取每次創建堆的循環條件if(2*j+2<=arr.length-1){//判斷當前a[2*j+2]是否存在,存在則執行a[j]、a[2*j+1]、a[2*j+2]比較,不存在則執行a[j]、a[2*j+1]比較temp=arr[j]>arr[2*j+1]?(arr[j]>arr[2*j+2]?j:2*j+2):(arr[2*j+1]>arr[2*j+2]?2*j+1:2*j+2);//比較獲得最大數的腳標}else{temp=arr[j]>arr[2*j+1]?j:2*j+1; }if(arr[j]==arr[temp]){//如果最大的數就是a[j]本身則退出進行下一次比較continue;}else{//最大數不是a[j]則最大數與a[j]交換位置arr[j]=arr[j]^arr[temp];arr[temp]=arr[j]^arr[temp];arr[j]=arr[j]^arr[temp];}}}}?運行結果:
?
?
轉載于:https://www.cnblogs.com/pipixiao/p/7687930.html
總結
以上是生活随笔為你收集整理的【知了堂学习笔记】java 编写几种常见排序算法3的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【Geek软技能】程序员,为什么写不好一
- 下一篇: 【UOJ】67 新年的毒瘤 【BZOJ】