今天有感,記錄於此 java
1、冒泡排序 算法
public static void bubbleSort(int[] arr){ for(int i=0;i<arr.length-1;i++){ for(int j=0;j<arr.length-i-1;j++){ if(arr[j+1]<arr[j]){ int temp=arr[j]; arr[j]=arr[j+1]; arr[j+1]=temp; } } } for (int i : arr) { System.out.println(i); } }
冒泡排序法存在的不足及改進方法: shell
第一,在排序過程當中,執行完最後的排序後,雖然數據已所有排序完備,但程序沒法判斷是否完成排序,爲了解決這一不足,可設置一個標誌位flag,將其初始值設置爲非0,表示被排序的表是一個無序的表,每一次排序開始前設置flag值爲0,在進行數據交換時,修改flag爲非0。在新一輪排序開始時,檢查此標誌,若此標誌爲0,表示上一次沒有作過交換數據,則結束排序;不然進行排序; ui
public static void bubbleSort(int[] arr){ int flag;//標識位 for(int i=0;i<arr.length-1;i++){ flag=0; for(int j=0;j<arr.length-i-1;j++){ if(arr[j+1]<arr[j]){ int temp=arr[j]; arr[j]=arr[j+1]; arr[j+1]=temp; flag=1;//發生了交換,標識位置爲1 } } if(flag==0)//此趟循環沒有發生數據交換,證實排序完成,直接跳出循環 break; } for (int i : arr) { System.out.println(i); } }
2、快速排序 spa
public static void quickSort(int arr[],int low,int high){ int i=low; int j=high; int key=arr[low];//選擇第一個元素做爲樞紐元素 if(low<high){ while(i<j){ while(i<j&&arr[j]>=key){ j--; } if(i<j){ arr[i]=arr[j]; i++; } while(i<j&&arr[i]<=key){ i++; } if(i<j){ arr[j]=arr[i]; j--; } } arr[i]=key; sort(arr,low,i-1); sort(arr,i + 1,high); } }
3、插入排序 code
public static void insertSort(int[] arr){ for(int i=1;i<arr.length;i++){ for(int j=i;(j>0&&arr[j]<arr[j-1]);j--){//下一個元素插入前面排好的數值 int temp=arr[j]; arr[j]=arr[j-1]; arr[j-1]=temp; } } }
4、選擇排序 排序
每一趟從待排序的數據元素中選出最小(或最大)的一個元素,順序放在已排好序的數列的最後,直到所有待排序的數據元素排完。 選擇排序是不穩定的排序方法。 class
public static void selectSort(int[] arr){ for(int i=0;i<arr.length;i++){ int min=arr[i]; int index=i; for(int j=i;j<arr.length-1;j++){//找出爲分組的最小數值 if(arr[j+1]<min){ min=arr[j+1]; index=j+1; } } arr[index]=arr[i]; arr[i]=min; } }
5、shell 排序 變量
public static void shellSort(int[] arr,int index){ for(int i=0;i<index&&i<arr.length;i++){ int count=(arr.length-1-i)/index; int[] temparr=new int[count+1]; for(int j=0;j<=count;j++){ temparr[j]=arr[i+j*index]; } insertSort(temparr); for(int j=0;j<=count;j++){ arr[i+j*index]=temparr[j]; } } index=index-1; if(index>0) shellSort(arr,index); }
在oschina上看見了別人的算法,牛的一逼 select
public static int[] shellSort(int[] arr){ int i,j,n=1,temp,len = arr.length; while(n<=len/3) n = n*3+1; while(n > 0){ for (i = n; i < len; i++) { temp = (Integer) arr[i]; j = i; while(j >= n && (Integer)arr[j - n] >= temp){ arr[j] = arr[j - n]; j-=n; } arr[j] = temp; } n = (n - 1)/3; } return arr; }那個for裏面的寫的太精彩了
6、堆排序
1)將初始待排序關鍵字序列(R1,R2....Rn)構建成大頂堆,此堆爲初始的無序區;
2)將堆頂元素R[1]與最後一個元素R[n]交換,此時獲得新的無序區(R1,R2,......Rn-1)和新的有序區(Rn),且知足R[1,2...n-1]<=R[n];
3)因爲交換後新的堆頂R[1]可能違反堆的性質,所以須要對當前無序區(R1,R2,......Rn-1)調整爲新堆,而後再次將R[1]與無序區最後一個元素交換,獲得新的無序區(R1,R2....Rn-2)和新的有序區(Rn-1,Rn)。不斷重複此過程直到有序區的元素個數爲n-1,則整個排序過程完成。
對於堆排序,最重要的兩個操做就是構造初始堆和調整堆 :
/** * 創建堆 * * @param args */ public static void bulidHeap(int[] arr, int size) { int i; for (i = (arr.length / 2) - 1; i >= 0; i--) // 非葉節點最大序號值爲size/2 { swapHeap(arr, i, size); } } /** * 調整堆 * @param args */ public static void swapHeap(int[] arr, int i, int size) { int lchild = 2 * i + 1; // i的左孩子節點序號 int rchild = 2 * i + 2; // i的右孩子節點序號 int max = i; // 臨時變量 if (i <= size / 2) // 若是i是葉節點就不用進行調整 { if (lchild < size && arr[lchild] > arr[max]) { max = lchild; } if (rchild < size && arr[rchild] > arr[max]) { max = rchild; }//取得max爲父子結點中,最大的結點index if (max != i) { int temp = arr[max]; arr[max] = arr[i]; arr[i] = temp; swapHeap(arr, max, size); // 避免調整以後以max爲父節點的子樹不是堆,繼續調整爲大頂堆 } } }
/** * 堆排序 * * @param args */ public static void heapSort(int[] arr) { bulidHeap(arr, arr.length);// 構建初始堆 for (int i = arr.length - 1; i > 0; i--) {//選擇堆中第一個元素與最後一個元素交互,從新調整堆,以此類推 int temp = arr[0]; arr[0] = arr[i]; arr[i] = temp; swapHeap(arr, 0, i);//從新調整餘下元素,chengw } }
end