1. 程式人生 > >java開發過程中幾種常用演算法

java開發過程中幾種常用演算法

排序演算法

排序演算法中包括:簡單排序、高階排序

 

簡單排序

 簡單排序常用的有:氣泡排序、選擇排序、插入排序

  • 氣泡排序程式碼如下:
 1 private static void bubbleSrot(int[] arr) {
 2 
 3 for (int i = 0; i < arr.length - 1; i++) {
 4 
 5 for (int j = i + 1; j < arr.length; j++) {
 6 
 7 if (arr[i] > arr[j]) {
 8 
 9 int temp = arr[i];
10 11 arr[i] = arr[j]; 12 13 arr[j] = temp; 14 15 } 16 17 } 18 19 } 20 21 }

   氣泡排序方法速度是很慢的,執行時間為O(N²)級。選擇排序改進了氣泡排序,將必要的交換次數從O(N²)減少到O(N),不幸的是比較次數依然是O(N²)級。然而,選擇排序依然為大記錄量的排序提出了一個非常重要的改進,因為這些大量的記錄需要在記憶體中移動,這就使交換的時間和比較的時間相比起來,交換的時間更為重要。
---------------------

  • 選擇排序程式碼如下:
 1 private
static void chooseSort(int[] arr) { 2 3 for (int i = 0; i < arr.length; i++) { 4 5 int least = i; 6 7 for (int j = i + 1; j < arr.length; j++) { 8 9 if (arr[j] < arr[least]) { 10 11 least = j; 12 13 } 14 15 } 16 17 // 將當前第一個元素與它後面序列中的最小的一個 元素交換,也就是將最小的元素放在最前端 18 19 int temp = arr[i];
20 21 arr[i] = arr[least]; 22 23 arr[least] = temp; 24 25 } 26 27 }

   選擇排序的效率:選擇排序和氣泡排序執行了相同次數的比較:N*(N-1)/2。對於10個數據項,需要45次比較,然而,10個數據項只需要少於10次的交換。對於100個數據項,需要4950次比較,但只進行不到100次交換。N值很大時,比較的次數是主要的,所以結論是選擇排序和冒泡哦排序一樣運行了O(N²)時間。但是,選擇排序無疑更快,因為它進行的交換少得多。
---------------------

  • 插入排序程式碼如下
 1 private static void insertionSort(int[] arr) {
 2 
 3 int in, out;
 4 
 5 for (out = 1; out < arr.length; out++) {
 6 
 7 int temp = arr[out];
 8 
 9 in = out;
10 
11 while (in > 0 && arr[in - 1] >= temp) {
12 
13 arr[in] = arr[in - 1];
14 
15 --in;
16 
17 }
18 
19 arr[in] = temp;
20 
21 }
22 
23 }

   插入排序的效率:這個演算法中,第一趟排序,最多比較一次,第二趟排序,最多比較兩次,以此類推,最後一趟最多比較N-1次,因此有1+2+3+…+N-1 = N*(N-1)/2。然而,因為在每一趟排序發現插入點之前,平均只有全體資料項的一半真的進行了比較,所以除以2最後是N*(N-1)/4。
對於隨機順序的資料,插入排序也需要O(N²)的時間級。當資料基本有序,插入排序幾乎只需要O(N)的時間,這對把一個基本有序的檔案進行排序是一個簡單而有效的方法。
  對於逆序排列的資料,每次比較和移動都會執行,所以插入排序不比氣泡排序快。
---------------------

  • 歸併排序

 1 // 將兩個已排序的數組合併到第三個陣列上。
 2 
 3 private static void merge(int[] arrA, int[] arrB, int[] arrC) {
 4 
 5 int aDex = 0, bDex = 0, cDex = 0;
 6 
 7 int sizeA = arrA.length;
 8 
 9 int sizeB = arrB.length;
10 
11 
12 // A陣列和B陣列都不為空
13 
14 while (aDex < sizeA && bDex < sizeB) {
15 
16 if (arrA[aDex] < arrB[bDex]) {
17 
18 arrC[cDex++] = arrA[aDex++];
19 
20 } else {
21 
22 arrC[cDex++] = arrB[bDex++];
23 
24 }
25 
26 }
27 
28 // A陣列不為空,B陣列為空
29 
30 while (aDex < sizeA) {
31 
32 arrC[cDex++] = arrA[aDex++];
33 
34 }
35 
36 // A陣列為空,B陣列不為空
37 
38 while (bDex < sizeB) {
39 
40 arrC[cDex++] = arrB[bDex++];
41 
42 }
43 
44 }

 

 

高階排序

  常見的高階排序:雜湊排序、快速排序,這兩種排序演算法都比簡單排序演算法快得多:希爾排序大約需要O(N*(logN)²)時間,快速排序需要O(N*logN)時間。這兩種排序演算法都和歸併排序不同,不需要大量的輔助儲存空間。希爾排序幾乎和歸併排序一樣容易實現,而快速排序是所有通用排序演算法中最快的一種排序演算法。 還有一種基數排序,是一種不常用但很有趣的排序演算法。

 

  • 雜湊排序

  雜湊排序是基於插入排序的,實現程式碼如下:

 1 private static void shellSort(int[] arr) {
 2 
 3 int inner, outer;
 4 
 5 int temp;
 6 
 7 int h = 1;
 8 
 9 int nElem = arr.length;
10 
11 while (h <= nElem / 3) {
12 
13 h = h * 3 + 1;
14 
15 }
16 
17 while (h > 0) {
18 
19 for (outer = h; outer < nElem; outer++) {
20 
21 temp = arr[outer];
22 
23 inner = outer;
24 
25 while (inner > h - 1 && arr[inner - h] >= temp) {
26 
27 arr[inner] = arr[inner - h];
28 
29 inner -= h;
30 
31 }
32 
33 arr[inner] = temp;
34 
35 }
36 
37 h = (h - 1) / 3;
38 
39 }
40 
41 }
42 --------------------- 

 

  • 快速排序

  快速排序是最流行的排序演算法,在大多數情況下,快速排序都是最快的,執行時間是O(N*logN)級,劃分是快速排序的根本機制。劃分本身也是一個有用的操作。 劃分資料就是把資料分為兩組,使所有關鍵字大於特定值的資料項在一組,所有關鍵字小於特定值的資料項在另一組。程式碼實現如下:

 1 // 快速排序
 2 
 3 private static void recQuickSort(int arr[], int left, int right) {
 4 
 5 if (right - left <= 0) {
 6 
 7 return;
 8 
 9 } else {
10 
11 int pivot = arr[right];// 一般使用陣列最右邊的元素作為樞紐
12 
13 int partition = partitionIt(arr, left, right, pivot);
14 
15 recQuickSort(arr, left, partition - 1);
16 
17 recQuickSort(arr, partition + 1, right);
18 
19 }
20 
21 }
22 
23 
24 // 劃分
25 
26 private static int partitionIt(int[] arr, int left, int right, int pivot) {
27 
28 int leftPtr = left - 1;
29 
30 // int rightPtr = right + 1;
31 
32 int rightPtr = right; // 使用最右邊的元素作為樞紐,劃分時就要將最右端的資料項排除在外
33 
34 while (true) {
35 
36 while (arr[++leftPtr] < pivot)
37 
38 ;
39 
40 while (rightPtr > 0 && arr[--rightPtr] > pivot)
41 
42 ;
43 
44 
45 if (leftPtr >= rightPtr) {
46 
47 break;
48 
49 } else {
50 
51 // 交換leftPtr和rightPtr位置的元素
52 
53 int temp = arr[leftPtr];
54 
55 arr[leftPtr] = arr[rightPtr];
56 
57 arr[rightPtr] = temp;
58 
59 }
60 
61 }
62 
63 // 交換leftPtr和right位置的元素
64 
65 int temp = arr[leftPtr];
66 
67 arr[leftPtr] = arr[right];
68 
69 arr[right] = temp;
70 
71 return leftPtr;// 返回樞紐位置
72 
73 }
74 --------------------- 

 

 

查詢演算法

對於有序的陣列,常用的查詢演算法:二分查詢。程式碼如下:

 

 1 private static int find(int [] arr,int searchKey){
 2 
 3         int lowerBound = 0;
 4 
 5         int upperBound = arr.length -1;
 6 
 7         int curIn;
 8 
 9         while(lowerBound <= upperBound){
10 
11             curIn = (lowerBound + upperBound) / 2;
12 
13             if(arr[curIn] == searchKey){
14 
15                 return curIn;
16 
17             }else{
18 
19                 if(arr[curIn] < searchKey){
20 
21                     lowerBound = curIn + 1;
22 
23                 }else{
24 
25                     upperBound = curIn - 1;
26 
27                 }
28 
29             }
30 
31         }
32 
33         return -1;
34 
35     }
36 ---------------------