面試的時候排序是經常會被問到的問題,能夠考察程序員的算法基礎知識,常用的排序主要有冒泡、選擇、插入和快速排序,下面簡單的介紹每一個排序的基本思想:
一、冒泡排序:將臨近的數字兩兩進行比較,按照從小到大或者從大到小的順序進行交換,每排一次最後出現一個最大值或是最小值排在序列的第一個或最後一個位置.
代碼展示如下:BubbleSort.java
package cn.java.sort;
public class BubbleSort {
public void bubble(int[] data)
{
/**每次將大的數排列在最後
for (int i = 0; i < data.length; i++) {
for (int j = 1; j < data.length-i; j++) {
if (data[j]<data[j-1]) {
Swap.swap(data, j, j-1);
}
}
}**/
/**
* 每次出現一個最小值排列在序列的最前面
*/
for (int i = 0; i < data.length; i++) {
for (int j = data.length-1; j >i; j--) {
if (data[j]<data[j-1]) {
Swap.swap(data, j, j-1);
}
}
}
}
}
二、選擇排序:每一趟在n-i+1(i=1,2,…n-1)個記錄中選取關鍵字最小的記錄作爲有序序列中第i個記錄,每一次比較的時候找出一個最小或最大的排在第一或者最後一個位置上都可.
代碼展示如下:SelectSort.java
package cn.java.sort;
public class SelectSort {
public void select(int[] data) {
for (int i = 0; i < data.length; i++) {
int index=i;
for (int j = data.length-1; j >i; j--) {
if (data[j]<data[index]) {
index=j;
}
}
Swap.swap(data, i, index);
}
}
}
代碼展示如下:InsertSort.java
package cn.java.sort;
public class InsertSort {
public void insert(int[] data) {
for (int i = 1; i < data.length; i++) {
for (int j = i; j>0&&data[j]<data[j-1]; j--) {
Swap.swap(data, j, j-1);
}
}
}
}
四、快速排序:像合併排序一樣,快速排序是基於分支模式的:
1)、分解:數組A[n]被劃分兩個字數組A[0..q-1]和A[q+1..n],使得對於數組A[0..q-1]中的元素都小於A[q], A[q+1..n]中的元素都大於等於A[q]。此時A[q]就得排好序;
2)、解決:通過遞歸調用快速排序,對字數組A[0..q-1]和A[q+1..n]進行排;
3)、合併:因爲兩個字數組已經是就地排好序的了,整個數組已經排好序了.
通過一次分割,將無序序列分成兩部分,左邊部分的元素值均比右邊部分的元素值小,且都不大於分割的基準值
代碼展示如下:QuickSort.java
package cn.java.sort;
public class QuickSort {
public void quick(int[] data) {
quickDiv(data,0,data.length-1);
}
public void quick2(int[] data) {
if (data.length>0) {
quickDiv2(data, 0, data.length-1);
}
}
private void quickDiv2(int[] data, int low, int high) {
if (low<high) {
int mid=getMiddle(data,low,high);//對數組進行分割
quickDiv2(data, low, mid-1);//對中軸左邊進行遞歸排序
quickDiv2(data, mid+1, high);//對中軸右邊進行遞歸排序
}
}
private int getMiddle(int[] data, int low, int high) {
int temp=data[low];//以數組第一個作爲中軸
while (low<high) {//從右向左遍歷
while (low<high&&temp<=data[high]) {
high--;
}
data[low]=data[high];
while (low<high&&data[low]<=temp) {//從左向右遍歷
low++;
}
data[high]=data[low];
}
data[low]=temp; //中軸的位置
return low;
}
private void quickDiv(int[] data, int i, int j) {
int pivotIndex=(i+j)/2;
Swap.swap(data, pivotIndex, j);
int k=partition(data,i-1,j,data[j]);
Swap.swap(data, k, j);
if((k-i)>1) quickDiv(data, i, k-1);
if((j-k)>1) quickDiv(data, k+1, j);
}
private int partition(int[] data, int l, int r, int pivot) {
do {
while (data[++l]<pivot) ;
while ((r!=0)&&data[--r]>pivot) ;
Swap.swap(data, l, r);
} while (l<r);
Swap.swap(data, l, r);
return l;
}
}
四、測試程序和代碼展示
1)、Swap.java
package cn.java.sort;
public class Swap {
public final static int[] TEST_ARRAY=new int[]{3,75,21,44,32,56,5,36,19,66};
public static void swap(int[] data,int i,int j)
{
int temp=data[i];
data[i]=data[j];
data[j]=temp;
}
public static void display(int[] data)
{
for (int i = 0; i < data.length; i++) {
System.out.print(data[i]+" ");
}
System.out.println("\n--------------------");
}
}
2)、TestSort.java
package cn.java.sort;
public class TestSort {
public static void main(String[] args) {
Swap.display(Swap.TEST_ARRAY);
//new BubbleSort().bubble(Swap.TEST_ARRAY);
//new SelectSort().select(Swap.TEST_ARRAY);
//new InsertSort().insert(Swap.TEST_ARRAY);
//new QuickSort().quick2(Swap.TEST_ARRAY);
new QuickSort().quick(Swap.TEST_ARRAY);
Swap.display(Swap.TEST_ARRAY);
}
}
5)、測試result
3 75 21 44 32 56 5 36 19 66
--------------------
3 5 19 21 32 36 44 56 66 75
--------------------