面试的时候排序是经常会被问到的问题,能够考察程序员的算法基础知识,常用的排序主要有冒泡、选择、插入和快速排序,下面简单的介绍每一个排序的基本思想:
一、冒泡排序:将临近的数字两两进行比较,按照从小到大或者从大到小的顺序进行交换,每排一次最后出现一个最大值或是最小值排在序列的第一个或最后一个位置.
代码展示如下: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
--------------------