日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

排序算法java实现

發布時間:2023/12/4 编程问答 26 豆豆
生活随笔 收集整理的這篇文章主要介紹了 排序算法java实现 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

1. 插入排序

  原理:遍歷到第N個元素的時候前面的N-1個元素已經是排序好的了,那么就查找前面的N-1個元素把這第N個元素放在合適的位置,如此下去直到遍歷完序列的元素為止。
? ? 算法的復雜度也是簡單的,排序第一個需要1的復雜度,排序第二個需要2的復雜度,因此整個的復雜度就是
? ? 1 + 2 + 3 + …… + N = O(N ^ 2)的復雜度。

// 插入排序 void InsertSort(int array[], int length) {int i, j, key;for (i = 1; i < length; i++){key = array;// 把i之前大于array的數據向后移動for (j = i - 1; j >= 0 && array[j] > key; j--){array[j + 1] = array[j];}// 在合適位置安放當前元素array[j + 1] = key;} }

2.shell排序  

原理:將序列分成子序列,然后分別對子序列進行排序,最后將子序列組合起來。每次排序把序列的元素按照某個增量分成幾個子序列對這幾個子序列進行插入排序,然后不斷的縮小增量擴大每個子序列的元素數量,直到增量為一的時候子序列就和原先的待排列序列一樣了,此時只需要做少量的比較和移動就可以完成對序列的排序了。

// shell排序 void ShellSort(int array[], int length) {int temp;// 增量從數組長度的一半開始,每次減小一倍for (int increment = length / 2; increment > 0;increment /= 2)for (int i = increment; i < length; ++i){temp = array;// 對一組增量為increment的元素進行插入排序for (int j = i; j >= increment; j -= increment){// 把i之前大于array的數據向后移動if (temp < array[j - increment]){array[j] = array[j - increment];}else{break;}}// 在合適位置安放當前元素array[j] = temp;} }

3.冒泡排序?

原理:每次遍歷完序列都把最大(小)的元素放在最前面,然后再對剩下的序列重復前面的一個過程,每次遍歷完之后待排序序列就少一個元素,當待排序序列減小為只有一個元素的時候排序就結束了。因此,復雜度在最壞的情況下是O(N ^ 2)?冒泡排序是穩定的,不會改變相同元素的相對順序

void  Swap( int   * a,  int   * b){int  temp;temp  =   * a;* a    =   * b;* b    =  temp; }//  冒泡排序void  BubbleSort( int  array[],  int  length){//  記錄一次遍歷中是否有元素的交換,總是與相鄰的元素比較,并向前移bool  exchange;for  ( int  i = 0 ; i<length;++ i){exchange= false ;for  ( int j=i+1 ; j< length;++j){if  (array[j] < array){exchange= true ;Swap( & array[j],  & array);}}//  如果這次遍歷沒有元素的交換,那么排序結束if  ( false   ==  exchange)break ;} }

4.快速排序?

原理:選定一個樞紐元素,對待排序序列進行分割,分割之后的序列一個部分小于樞紐元素,一個部分大于樞紐元素,再對這兩個分割好的子序列進行上述的過程?!?/p>

  假設輸入的數組中有k個小于軸值的結點,于是這些結點被放到數組最左邊的k個位置上,而大于軸值得被放到數組最右邊的n-k個位置上。

// 對一個給定范圍的子序列選定一個樞紐元素,執行完函數之后返回分割元素所在的位置, // 在分割元素之前的元素都小于樞紐元素,在它后面的元素都大于這個元素 int Partition(int array[], int low, int high) {// 采用子序列的第一個元素為樞紐元素int pivot = array[low];while (low < high){// 從后往前在后半部分中尋找第一個小于樞紐元素的元素while (low < high && array[high] >= pivot){--high;}// 將這個比樞紐元素小的元素交換到前半部分Swap(&array[low], &array[high]);// 從前往后在前半部分中尋找第一個大于樞紐元素的元素while (low < high && array[low] <= pivot){++low;}// 將這個比樞紐元素大的元素交換到后半部分Swap(&array[low], &array[high]);}// 返回樞紐元素所在的位置return low; }// 快速排序 void QuickSort(int array[], int low, int high) {if (low < high){int n = Partition(array, low, high);QuickSort(array, low, n);QuickSort(array, n + 1, high);} }

 5. 歸并排序

 原理:把待排序序列分成相同大小的兩個部分,依次對這兩部分進行歸并排序,完畢之后再按照順序進行合并

 兩個(或兩個以上)有序表合并成一個新的有序表,即把待排序的序列分成若干個子序列,每個子序列都是有序的,然后把有序子序列合并成整體有序序列,這個過程也稱為2-路歸并.歸并排序的一種穩定排序,即相等元素的順序不會改變.時間復雜度為O(nlogn),空間復雜度為log(n)

// 歸并排序中的合并算法 void Merge(int array[], int start, int mid, int end) {int temp1[10], temp2[10];int n1, n2;n1 = mid - start + 1;n2 = end - mid;// 拷貝前半部分數組for (int i = 0; i < n1; i++){temp1 = array[start + i];}// 拷貝后半部分數組for (int i = 0; i < n2; i++){temp2 = array[mid + i + 1];}// 把后面的元素設置的很大temp1[n1] = temp2[n2] = 1000;// 逐個掃描兩部分數組然后放到相應的位置去for (int k = start, i = 0, j = 0; k <= end; k++){if (temp1 <= temp2[j]){array[k] = temp1;i++;}else{array[k] = temp2[j];j++;}} }// 歸并排序 void MergeSort(int array[], int start, int end) {if (start < end){int i;i = (end + start) / 2;// 對前半部分進行排序MergeSort(array, start, i);// 對后半部分進行排序MergeSort(array, i + 1, end);// 合并前后兩部分Merge(array, start, i, end);} }

 6.選擇排序

原理 :?每一趟從待排序的數據元素中選出最小(或最大)的一個元素,?順序放在已排好序的數列的最后,直到全部待排序的數據元素排完。?選擇排序是不穩定的排序方法。

  第i次是選擇數組中第i小的記錄,并將該記錄放到數組的第i個位置。

package sort.select; import java.util.Random; /*** @author liangge* */ public class Main {public static void main(String[] args) {Random ran = new Random();int[] sort = new int[10];for (int i = 0; i < 10; i++) {sort[i] = ran.nextInt(50);}System.out.print("排序前的數組為");for (int i : sort) {System.out.print(i + " ");}selectSort(sort);System.out.println();System.out.print("排序后的數組為");for (int i : sort) {System.out.print(i + " ");}}/*** 選擇排序* @param sort*/private static void selectSort(int[] sort){for(int i =0;i<sort.length-1;i++){for(int j = i+1;j<sort.length;j++){if(sort[j]<sort[i]){int temp = sort[j];sort[j] = sort[i];sort[i] = temp;}}}} }

7.堆排序

堆的定義:

n個關鍵字序列Kl,K2,…,Kn稱為堆,當且僅當該序列滿足如下性質(簡稱為堆性質):

(1) ki≤K2i且ki≤K2i+1 或(2)Ki≥K2i且ki≥K2i+1(1≤i≤)

  滿足Key[i]>=Key[2i+1]&&key>=key[2i+2]稱為大頂堆,滿足 Key[i]<=key[2i+1]&&Key[i]<=key[2i+2]稱為小頂堆。由上述性質可知大頂堆的堆頂的關鍵字肯定是所有關鍵字中最大的,小頂堆的堆頂的關鍵字是所有關鍵字中最小的

若將此序列所存儲的向量R[1……n]看做是一棵完全二叉樹的存儲結構,則堆實質上是滿足如下性質的完全二叉樹:樹中任一非葉結點的關鍵字均不大于(或不小于)其左右孩子(若存在)結點的關鍵字。

堆的這個性質使得可以迅速定位在一個序列之中的最小(大)的元素。

堆排序算法的過程如下:1)得到當前序列的最小(大)的元素 2)把這個元素和最后一個元素進行交換,這樣當前的最小(大)的元素就放在了序列的最后,而原先的最后一個元素放到了序列的最前面 3)的交換可能會破壞堆序列的性質(注意此時的序列是除去已經放在最后面的元素),因此需要對序列進行調整,使之滿足于上面堆的性質。重復上面的過程,直到序列調整完畢為止。

// array是待調整的堆數組,i是待調整的數組元素的位置,length是數組的長度 void HeapAdjust(int array[], int i, int nLength) {int nChild, nTemp;for (nTemp = array; 2 * i + 1 < nLength; i = nChild){// 子結點的位置是 父結點位置 * 2 + 1nChild = 2 * i + 1;// 得到子結點中較大的結點if (nChild != nLength - 1 && array[nChild + 1] > array[nChild])++nChild;// 如果較大的子結點大于父結點那么把較大的子結點往上移動,替換它的父結點if (nTemp < array[nChild]){array = array[nChild];}else    // 否則退出循環{break;}}// 最后把需要調整的元素值放到合適的位置array = nTemp; }// 堆排序算法 void HeapSort(int array[], int length) {// 調整序列的前半部分元素,調整完之后第一個元素是序列的最大的元素for (int i = length / 2 - 1; i >= 0; --i){HeapAdjust(array, i, length);}// 從最后一個元素開始對序列進行調整,不斷的縮小調整的范圍直到第一個元素for (int i = length - 1; i > 0; --i){// 把第一個元素和當前的最后一個元素交換,// 保證當前的最后一個位置的元素都是在現在的這個序列之中最大的Swap(&array[0], &array);// 不斷縮小調整heap的范圍,每一次調整完畢保證第一個元素是當前序列的最大值HeapAdjust(array, 0, i);} }

時間復雜度: 

  ? ? ? ? ?平均情況?最好情況?最壞情況?

歸并排序?O(nlogn)?O(nlogn)?O(nlogn)?

快速排序?O(nlogn)?O(nlogn)?O(n2)?

希爾排序?O(n1.5)?O(n)?O(n1.5)?

插入排序?O(n2)?O(n)?O(n2)?

選擇排序?O(n2)?O(n2)?O(n2)?

堆排序:時間復雜度O(nlogn)?
選擇排序:時間復雜度O(n2)?
冒泡排序:時間復雜度O(n2)?

總結

以上是生活随笔為你收集整理的排序算法java实现的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。