说到面试,最常被问到的就是排序问题,面试官经常会要求你亲自写出来的排序方式就是冒泡排序、选择排序、、插入排序、快速排序、堆排序、归并排序。下面我就用根据自己的理解,对上述六总排序的思想逐一总结一下。
(1)冒泡排序
这个算法可以说是排序算法里的小白,如果这个算法都写不出来,那你就应该在工作和学习的过程中多注意锻炼一下算法方面的能力啦。
核心思想:比较和交换
(2)选择排序
这个排序算法也是小白级别的排序算法,主要是对冒泡排序算法的一种改进吧,避免了在便利数组过程中的元素交换操作
核心思想:不断找出剩余元素集合中最大(最小)元素的小标
(3)插入排序
这个排序虽然不难,但是被面试官问到的概率也很大
核心思想:不断在保证顺序的情况下插入新的元素
(4)快速排序
这个算法可以说是面试过程中被问到概率最大的排序算法,可是如果你能直接说出这个算法的核心思想,面试官常常就是不再让你写出具体实现过程。
核心思想:分组
(5)堆排序
这个算法有点意思,我个人认为它和选择排序有点相似,所不同的是,它们找出最大(最小)值得方法不同,选择排序选择的方法是遍历所有剩余元素,而堆排序是不断进行堆的调整找出最大(最小)元素。
核心思想:不断通过对堆的调整选出最大(最小)值
(6)归并排序
这个算法很经典,是采用了分治的思想实现的高效排序算法,所以也常常被面试官问到。
核心思想:递归地将已有子序列合并,得到完全有序的序列。
我个人针对这几种常用排序算法进行了简单的实现,例子中默认使用升序排序,具体实现如下:
/**
* @Descriptions 定义了多种排序方法的接口
* @author Zhangmeng
* 2015-8-6
*/
public interface BasicSort {
/**
* @Descriptions 冒泡排序
* @author Zhangmeng
* 2015-8-6
* @param a
*/
public void bubbleSort(int[] a) ;
/**
* @Descriptions 选择排序
* @author Zhangmeng
* 2015-8-6
* @param a
*/
public void selectSort(int[] a) ;
/**@Descriptions插入排序
* @author Zhangmeng
* 2015-8-6
* @param a
*/
public void insertSort(int[] a) ;
/**
* @Descriptions 堆排序
* @author Zhangmeng
* 2015-8-6
* @param a
*/
public void heapSort(int[] a);
/**
* @Descriptions 归并排序
* @author Zhangmeng
* 2015-8-6
* @param a
*/
public void mergeSort(int[] a);
/**
* @Descriptions 快速排序
* @author Zhangmeng
* 2015-8-6
* @param a
*/
void quickSort(int [] a);
}
/**
* @Descriptions 对多种排序的实现
* @author Zhangmeng
* 2015-8-6
*/
public class BasicSortImpl implements BasicSort {
private void swap(int[] a ,int x, int y) {
int tempt=a[x];
a[x]=a[y];
a[y]=tempt;
}
/**
* @Author Zhangmeng
* 2015-8-6
* @see com.soft.basicsort.BasicSort#bubbleSort(int[])
*/
@Override
public void bubbleSort(int[] a) {
int n=a.length;
for(int i=0;i<n;i++){
for(int j=0;j<n-i-1;j++){
if(a[j]>a[j+1]){
this.swap(a, j, j+1);
}
}
}
}
/**
* @Author Zhangmeng
* 2015-8-6
* @see com.soft.basicsort.BasicSort#selectSort(int[])
*/
@Override
public void selectSort(int[] a) {
int n=a.length;
for(int i=0;i<n;i++){
int flag=i;
for(int j=i;j<n;j++){
if(a[j]<a[flag]){
flag=j;
}
}
this.swap(a, i, flag);
}
}
/**
* @Author Zhangmeng
* 2015-8-6
* @see com.soft.basicsort.BasicSort#insertSort(int[])
*/
@Override
public void insertSort(int[] a) {
int n=a.length;
for(int i=1;i<n;i++){
int tempt= a[i];
int j=i;
while(j>0 && a[j-1]>tempt){
a[j]=a[j-1];
j--;
}
a[j]=tempt;
}
}
/**
* @Author Zhangmeng
* 2015-8-6
* @see com.soft.basicsort.BasicSort#quickSort(int[])
*/
@Override
public void quickSort(int[] a) {
quickSort(a, 0, a.length-1);
}
public void quickSort(int[] a, int low, int high) {
//是否到达极限
if(low >= high){
return ;
}
//分组
int l = low; //低位下标
int h = high; //高位下标
int flag = a[low]; //分组标识
while(l<h){
//h->h 寻找第一个比flag小的值
while(l<h && a[h] > flag){
h --;
}
//填坑 ,坑在低位
a[low]=a[h];
//l->h 寻找第一个比flag大的值
while(l<h && a[l]<flag){
l ++;
}
//填坑,坑在高位
a[h]=a[l];
}
//填最终的坑
a[l]=flag;
//递归进行分组
quickSort(a, low, l-1);
quickSort(a, l+1, high);
}
/**
* @Author Zhangmeng
* 2015-8-6
* @see com.soft.basicsort.BasicSort#mergeSort(int[])
*/
public void mergeSort(int[] a) {
new BasicSortImpl().MergeSort(a, 0, a.length-1, new int[a.length]);
}
protected void MergeSort(int[] a, int first, int last, int temp[]) {
//如果至少两个元素 first<last
if(first<last){
//数组分成左右两个部分
//取中间坐标 mid
int mid=(first+last)/2;
int first1=first,last1=mid;
int first2=mid+1,last2=last;
//对左半部排序
this.MergeSort(a, first1, last1, temp);
//对右半部排序
this.MergeSort(a, first2, last2, temp);
//归并合并左右两部分
int j=0;
while(first1<=last1 && first2<=last2){
if(a[first1]<a[first2]){
temp[j++]=a[first1++];
}else{
temp[j++]=a[first2++];
}
}
//将左半部分剩余元素加入tempt
while(first1<=last1){
temp[j]=a[first1++];
j++;
}
//将有半部分剩余部分加入tempt
while(first2<=last2){
temp[j]=a[first2++];
j++;
}
//tempt[0,j-1]->a[first,last]
for(int i=0;i<j;i++){
a[first]=temp[i];
first++;
}
}
}
/**
* @Author Zhangmeng
* 2015-8-6
* @see com.soft.basicsort.BasicSort#heapSort(int[])
*/
@Override
public void heapSort(int[] a) {
buildHeap(a);
for(int i=a.length-1;i>=0;i--){
swap(a, 0, i);
heapAjust(a, 0,i-1);
}
}
private void heapAjust(int[] a,int i , int end){
int left=i*2+1;
int right=i*2+2;
int max=i;
if(left<end && a[max]<a[left]){
max=left;
}
if(right<end && a[max]<a[right]){
max=right;
}
if(max!=i){
swap(a, i, max);
heapAjust(a, max, end);
}
}
private void buildHeap(int[] a){
for(int i = a.length/2-1 ; i >= 0 ; i-- ){
heapAjust(a, i, a.length-1);
}
}
public static void main(String[] args) {
int a1[] = { 5, 4, 3, 2, 1, 0 };
int a2[] = { 5, 4, 3, 2, 1, 0 };
int a3[] = { 5, 4, 3, 2, 1, 0 };
int a4[] = { 5, 4, 3, 2, 1, 0 };
int a5[] = { 5, 4, 3, 2, 1, 0 };
int a6[] = { 5, 4, 3, 2, 1, 0 };
BasicSort sort = new BasicSortImpl();
sort.bubbleSort(a1);
System.out.print("冒泡排序结果:");
for (int data : a1) {
System.out.print(data+" ");
}
sort.selectSort(a2);
System.out.print("\n选择排序结果:");
for (int data : a2) {
System.out.print(data+" ");
}
sort.insertSort(a3);
System.out.print("\n插入排序结果:");
for (int data : a3) {
System.out.print(data+" ");
}
sort.mergeSort(a4);
System.out.print("\n归并排序结果:");
for (int data : a4) {
System.out.print(data + " ");
}
sort.quickSort(a5);
System.out.print("\n快速排序结果:");
for (int data : a5) {
System.out.print(data + " ");
}
sort.heapSort(a6);
System.out.print("\n堆排序结果:");
for (int data : a6) {
System.out.print(data + " ");
}
}
}