冒泡排序
//定義一個數組
int[] arr = new int[]{8,5,7,6,1,3,9,4};
//共比較多少輪
for (int i = 0; i < arr.length-1; i++) {
//一輪比較多少次
for (int j = 0; j < arr.length-1-i; j++) {
//如果前面的大於後面的,那麼前後交換
if (arr[j]>arr[j+1]){
int temp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = temp;
}
}
}
System.out.println(Arrays.toString(arr));
快速排序
/**
*
* @param arr:傳入的參數數組
* @param start:排序區間開始的下標
* @param end:排序區間結束的下標
*/
public static void quickSort(int[] arr,int start,int end){
//如果開始下標沒有與結束下標重合,則一直循環
if (start < end){
//將當前排序區間的第一個數作爲比較的標準數
int stard = arr[start];
//記錄排序需要的下標
int low = start;
int high = end;
//如果開始座標小於結束座標,則開始循環
while (low<high){
//如果開始座標小於結束座標並且右邊的數大於左邊的標準數
while (low<high&&stard<=arr[high]){
//結尾座標向前挪一位
high--;
}
//右邊結束座標的數替換掉左邊開始座標的數
arr[low] = arr[high];
//如果開始座標小於結束座標並且左邊的數小於標準數
while (low<high&&arr[low]<=stard){
//左邊數的下標向前挪一位
low++;
}
//左邊開始座標的數替換掉右邊結束座標的數
arr[high] = arr[low];
}
//當循環結束,即兩座標重疊時,將比較的標準數賦給當前座標的值
arr[low] = stard;
//重新開始比較標準數左邊的區間
quickSort(arr,start,low);
//重新開始比較標準數右邊的區間
quickSort(arr,low+1,end);
}
}
插入排序
public static void insertSort(int[] arr){
int temp;
int j = 0;
//從第二個遍歷整個數組
for (int i = 1; i < arr.length; i++) {
//如果當前數比前一個數小
if (arr[i]<arr[i-1]){
//把當前數存起來
temp = arr[i];
//遍歷當前數之前的所有的數
for (j = i-1; j >=0&&temp<arr[j] ; j--) {
//如果遍歷到的數大於temp,則向後挪一位
arr[j+1] = arr[j];
}
//當前的數小於等於temp,則把temp賦值給他後一位數
arr[j+1] = temp;
}
}
}
希爾排序
public static void shellSort(int[] arr){
//遍歷所有的步長
for (int d = arr.length/2; d >0 ; d/=2) {
//遍歷每一組中的第一個元素,與同一組的元素進行比較
for (int i = d; i < arr.length; i++) {
//遍歷本組中的所有元素
for (int j = i-d; j >=0 ; j-=d) {
if (arr[j]>arr[j+d]){
int temp = arr[j];
arr[j] = arr[j+d];
arr[j+d] = temp;
}
}
}
}
}
選擇排序
public static void chooseSort(int[] arr){
//遍歷所有的數
for (int i = 0; i <arr.length ; i++) {
int minIndex = i;
//把當前的數與之後所有的數全都比較一遍。並記錄下最小的數的下標
for (int j = i+1; j <arr.length ; j++) {
if (arr[j]<arr[minIndex]){
minIndex = j;
}
}
//將最小的數與當前遍歷的數交換
int temp = arr[i];
arr[i] = arr[minIndex];
arr[minIndex] = temp;
}
}
歸併排序
public static void MergeSort(int[] arr,int start,int end){
//取出中間下標
int middel = (start+end)/2;
//只要開始下標小於結束下標,就會一直遞歸
if (start<end){
//處理左邊的數組
MergeSort(arr,0,middel);
//處理右邊的數組
MergeSort(arr,middel+1,end);
//歸併排序
merge(arr,0,middel,end);
}
}
public static void merge(int[] arr,int low,int middel,int high){
//用於儲存歸併後的臨時數組
int[] temp = new int[high-low+1];
//記錄第一個數組中需要遍歷的下標
int i = low;
//記錄第二個數組中需要遍歷的下標
int j = middel+1;
//用於記錄在臨時數組中存放的下標
int index = 0;
//遍歷兩個數組中取出較小的數字,存放到新數組中
while (i<=middel&&j<=high){
//第一個數組的數字更小
if (arr[i]<=arr[j]){
temp[index] = arr[i];
//下標後移一位
i++;
//第二個數組的數字更小
}else {
temp[index] = arr[j];
j++;
}
index++;
}
//處理多餘的數據
while (j<=high){
temp[index]=arr[j];
j++;
index++;
}
while (i<=middel){
temp[index]=arr[i];
i++;
index++;
}
//把臨時數組中的數據重新存入原數組
for (int k = 0; k < temp.length; k++) {
arr[k+low] = temp[k];
}
}
基數排序
/**
* 採用數組形式
*/
public static void radixSort(int[] arr){
//定義一個最小值變量。Integer.MIN_VALUE:整形數中的最小值:-2147483648
int max = Integer.MIN_VALUE;
//遍歷找出數組中最大值
for (int i = 0; i < arr.length; i++) {
if (arr[i]>max){
max = arr[i];
}
}
//計算最大數組是幾位數
int maxLength = (max+"").length();
//定義一個臨時存儲數據的二維數組
int[][] temp = new int[10][arr.length];
//用於記錄temp相對數組中數據的數量
int[] count = new int[10];
//根據最大長度決定比較次數,即最大數是幾位數,則比較幾次
for (int i = 0,n=1; i < maxLength; i++,n*=10) {
//把每一個數字分別計算餘數,按餘數分組
for (int j = 0; j < arr.length; j++) {
//計算餘數
int ys = arr[j]/n%10;
//把當前遍歷的數據放入指定的數組中
temp[ys][count[ys]] = arr[j];
//當前數組數據數量+1
count[ys]++;
}
//記錄取的元素需要放的位置
int index = 0;
//再把分完組的數據重新放回原數組中
for (int k = 0; k <count.length ; k++) {
//判斷當前分組是否爲0
if (count[k]!=0)
//若不爲0,則遍歷取出當前分組的數據
for (int l = 0; l < count[k]; l++) {
//原數組從0開始,臨時數組從有數據的分組開始
arr[index] = temp[k][l];
//原數組下標+1
index++;
}
//取完後把count數組清空以便記錄下一次便利分組
count[k] = 0;
}
}
}
/**
* 採用隊列形式
*/
public static void radixSort_for_queue(int[] arr){
//定義一個最小值變量。Integer.MIN_VALUE:整形數中的最小值:-2147483648
int max = Integer.MIN_VALUE;
//遍歷找出數組中最大值
for (int i = 0; i < arr.length; i++) {
if (arr[i]>max){
max = arr[i];
}
}
//計算最大數組是幾位數
int maxLength = (max+"").length();
//定義一個臨時存儲數據的隊列的數組(即創建10個隊列)
QueueUtil[] temp = new QueueUtil[10];
//爲每一組隊列賦值
for (int i = 0; i < temp.length; i++) {
temp[i] = new QueueUtil();
}
//根據最大長度決定比較次數,即最大數是幾位數,則比較幾次
for (int i = 0,n=1; i < maxLength; i++,n*=10) {
//把每一個數字分別計算餘數,按餘數分組
for (int j = 0; j < arr.length; j++) {
//計算餘數
int ys = arr[j]/n%10;
//把當前遍歷的數據放入指定的隊列中
temp[ys].add(arr[j]);
}
//記錄取的元素需要放的位置
int index = 0;
//再把分完組的數據重新放回原數組中
for (int k = 0; k <temp.length ; k++) {
//判斷當前分組是否爲0
while (!temp[k].isEmpty()){
//原數組從0開始,隊列從有數據的開始
arr[index] = temp[k].pop();
//原數組下標+1
index++;
}
}
}
}
堆排序
/**
* 升序用大頂堆
* 降序用小頂堆
* */
public static void heapSort(int[] arr){
int start = (arr.length-1)/2;
//調整爲大頂堆
for (int i = start; i >=0; i--) {
maxHeap(arr,arr.length,i);
}
//先把數組中前後交換,然後再把前面的處理成大頂堆
for (int i = arr.length-1; i >0 ; i--) {
int temp = arr[0];
arr[0] = arr[i];
arr[i] = temp;
maxHeap(arr,i,0);
}
}
/**
* @param arr:傳遞的數組
* @param size:排序的範圍
* @param index:初始父節點
*/
public static void maxHeap(int[] arr,int size,int index){
//左子結點
int leftNode = 2*index+1;
//右子結點
int rightNode = 2*index+2;
//父節點
int max = index;
//與兩個子結點對比,找出最大節點
if (leftNode<size&&arr[leftNode]>arr[max]){
//如果左子結點大於父節點,那麼二者交換
max = leftNode;
}
if (rightNode<size&&arr[rightNode]>arr[max]){
//如果右子結點大於父節點,那麼二者交換
max = rightNode;
}
//交換位置
if (max != index){
int temp = arr[index];
arr[index] = arr[max];
arr[max] = temp;
maxHeap(arr,size,max);
}
//交換位置後,可能破壞之前排好的堆,所以需要重新調整之前排好的堆
}