java實現常用排序演算法
陣列排序問題是java工程師面試過程中很常見的問題之一,也是java程式設計師必備的知識。本文總結了用java實現常用的排序演算法。
注:陣列從小到大排序
1. 氣泡排序
特點:效率低,實現簡單,容易理解
思想:每一次遍歷,將待排序中最大的元素移到最後,剩下的為新的待排序序列,重複上述步驟直至排序完所有元素。
程式碼實現:
public void bubbleSort(int array[]){ int t = 0; for(int i = 0; i < array.length - 1; i++){ for(int j = 0; j < length.length - 1 - i; j++){ if(array[j] > array[j + 1]){ t = array[j]; array[j] = array[j + 1]; array[j + 1] = t; } } } }
2.選擇排序
特點:效率低,實現簡單,容易理解
思想:每一次遍歷,從待排序中選擇一個最小的元素放到已排序序列的末尾,剩下的為待排序序列,重複上述步驟直至排序完所有元素。
程式碼實現:
public void selectSort(int array[]) { int t = 0; for (int i = 0; i < array.length - 1; i++){ int index=i; for (int j = i + 1; j < array.length; j++){ if (array[index] > array[j]) index=j; } if(index!=i){ t = array[i]; array[i] = array[index]; array[index] = t; } } }
3. 插入排序
特點:效率低,容易實現,容易理解。
思想:將陣列分為兩部分,將後一部分的元素逐一與前部分進行比較,如果前部分元素比array[i]小,就將前部分元素往後移動。當沒有比array[i]小的元素,即是合理位置,在此位置插入array[i]
程式碼實現:
public void insertionSort(int array[]) { int i, j, t = 0; for (i = 1; i < array.length; i++) { if(a[i]<a[i-1]){ t = array[i]; for (j = i - 1; j >= 0 && t < array[j]; j--) array[j + 1] = array[j]; //插入array[i] array[j + 1] = t; } } }
4.快速排序
特點:高效,時間複雜度為NlogN。
思想:採用分治法的思想,首先設定一個軸值pivot(一般為第一個元素),然後以這個軸值為劃分基準,將待排序序列分成比pivot大和比pivot小的兩部分,接下來對劃分完的子序列進行快速排序直到子序列為一個元素為止。
程式碼實現:
public void quickSort(int array[], int low, int high) {// 傳入low=0,high=array.length-1;
int pivot, p_pos, i, t;// pivot->位索引;p_pos->軸值。
if (low < high) {
p_pos = low;
pivot = array[p_pos];
for (i = low + 1; i <= high; i++)
if (array[i] > pivot) {
p_pos++;
t = array[p_pos];
array[p_pos] = array[i];
array[i] = t;
}
t = array[low];
array[low] = array[p_pos];
array[p_pos] = t;
// 分而治之
quickSort(array, low, p_pos - 1);// 排序左半部分
quickSort(array, p_pos + 1, high);// 排序右半部分
}
}
5.堆排序
思想:利用堆的性質進行排序
堆分為兩類: 1、最大堆(大頂堆):堆的每個父節點都大於其孩子節點; 2、最小堆(小頂堆):堆的每個父節點都小於其孩子節點;
堆的儲存: 一般都用陣列來表示堆,i結點的父結點下標就為(i – 1) / 2。它的左右子結點下標分別為2 * i + 1和2 * i + 2。
堆的第一個元素要麼是最大值(大頂堆),要麼是最小值(小頂堆),這樣在排序的時候(假設共n個節點),直接將第一個元素和最後一個元素進行交換,然後從第一個元素開始進行向下調整至第n-1個元素。所以,如果需要升序,就建一個大堆,需要降序,就建一個小堆。 堆排序的步驟分為三步: 1、建堆(升序建大堆,降序建小堆); 2、交換資料; 3、向下調整。
程式碼實現:
void AdjustDown(int arr[], int i, int n)
{
int j = i * 2 + 1;//子節點
while (j<n)
{
if (j+1<n && arr[j] > arr[j + 1])//子節點中找較小的
{
j++;
}
if (arr[i] < arr[j])
{
break;
}
swap(arr[i],arr[j]);
i = j;
j = i * 2 + 1;
}
}
void MakeHeap(int arr[], int n)//建堆
{
int i = 0;
for (i = n / 2 - 1; i >= 0; i--)//((n-1)*2)+1 =n/2-1
{
AdjustDown(arr, i, n);
}
}
void HeapSort(int arr[],int len)
{
int i = 0;
MakeHeap(arr, len);
for (i = len - 1; i >= 0; i--)
{
swap(arr[i], arr[0]);
AdjustDown(arr, 0, i);
}
}