常见的面试中的排序算法

首先放上对比图,这图总结的很到位。html

1.直接插入排序

1.1基本思想:

假设有一个数组a[1..n],首先咱们能够认为在刚开始时a[1]是有序的,而后咱们从a[2]开始,到增个数组结束,依次将a[i]插入当前的有序区域中,就像整理扑克牌同样,直到遍历到数组的最后一位。java

1.2实现代码

public static void sis(String[] original, int from, int length) throws Exception {
        if (from < 0 || length < 0 || from + length > original.length) {
            throw new IllegalArgumentException("Array out of bound .");
        }
        for (int i = from + 1; i < from + length; i++) {
            String temp = original[i];
            int j = i - 1;
            while (j >= 0) {
                if (temp.compareTo(original[j]) < 0) {
                    original[j + 1] = original[j];
                } else {
                    break;
                }
                j--;
            }
            original[j + 1] = temp;
        }
    }

1.3算法分析

  1. 时间复杂度:O(N*N)
  2. 空间复杂度:O(1)
  3. 稳定性:稳定

2.shell排序

2.1 基本思想

shell排序对直接插入排序进行了简单的改进,他经过加大插入排序中元素之间的间隔,并在这些有间隔的元素中进行插入排序,从而使数据想大跨度地移动,当这些数据排过一趟以后,shell排序减少数据项之间的间隔再进行排序,依次进行下去,直到间隔为1。算法

2.2实现代码

public void shellSort(int[] array)
    {
        int increment = array.length;
        do
        {
            increment = increment / 2;  // 增量序列
            for (int i = increment; i < array.length; i++)
            {
                if (array[i] < array[i - increment])
                {
                    Integer guard = array[i];
                    int j;
                    for (j = i - increment; (j >= 0) && (guard < array[j]); j -= increment)     //  记录后移,查找插入位置
                    {
                        array[j + increment] = array[j];
                    }
                    array[j + increment] = guard;  // 插入
                }
            }
        } while (increment > 1);
    }

2.3算法分析

  1. 时间复杂度:O(N*logN)
  2. 空间复杂度:O(1)
  3. 稳定性:不稳定(通常来讲,若存在不相邻元素间交换,则极可能是不稳定的排序。)

3.直接选择排序

3.1 算法思想

首先在未排序的区域中找到最小的元素,放到已经排序的最后一位(刚开始的时候放在第一位),依次类推,直到最后一位。shell

3.2 实现代码

public static void select_sort(int[] a) {

        for (int i = 0; i < a.length; i++) {
            for (int j = i + 1; j < a.length; j++) {
                if (a[i] > a[j]) {
                    swap(a, i, j);
                }
            }
        }
}

    public static void swap(int[] a, int b, int c) {
        if (b == c)
            return;
        a[b] = a[b] ^ a[c];
        a[c] = a[b] ^ a[c];
        a[b] = a[b] ^ a[c];
    }

3.3 算法分析

  1. 时间复杂度:O(N*N)
  2. 空间复杂度:O(1)
  3. 稳定性:不稳定

4.堆排序

4.1 算法思想

利用彻底二叉树中双亲节点和孩子节点之间的的内在关系,在当前无序区中选择关键字最大(最小)的记录。也就是说,以最小堆为例,根节点为最小元素,较大的节点偏向分布于堆底部。windows

4.2  代码实现

//  从i节点开始调整,n为节点总数 从0开始计算 i节点的子节点为 2*i+1, 2*i+2  
void MinHeapFixdown(int a[], int i, int n)  
{  
    int j, temp;  
  
    temp = a[i];  
    j = 2 * i + 1;  
    while (j < n)  
    {  
        if (j + 1 < n && a[j + 1] < a[j]) //在左右孩子中找最小的  
            j++;  
  
        if (a[j] >= temp)  
            break;  
  
        a[i] = a[j];     //把较小的子结点往上移动,替换它的父结点  
        i = j;  
        j = 2 * i + 1;  
    }  
    a[i] = temp;  
}  
//在最小堆中删除数  
void MinHeapDeleteNumber(int a[], int n)  
{  
    Swap(a[0], a[n - 1]);  
    MinHeapFixdown(a, 0, n - 1);  
}

4.3 算法分析

  1. 时间复杂度:O(N*logN)
  2. 空间复杂度:O(1)
  3. 稳定性:不稳定
  4. 此外,创建堆的时间复杂度为O(N)

5. 冒泡排序

5.1 算法思想

经过无序区中相邻记录关键字间的比较和位置的交换,使关键字最小的记录如气泡通常逐渐往上“漂浮”直至“水面”。数组

5.2 实现代码

for (int i = 0; i < score.length -1; i++){    //最多作n-1趟排序  
            for(int j = 0 ;j < score.length - i - 1; j++){    //对当前无序区间score[0......length-i-1]进行排序(j的范围很关键,这个范围是在逐步缩小的)  
                if(score[j] > score[j + 1]){    //把大的值交换到后面  
                    int temp = score[j];  
                    score[j] = score[j + 1];  
                    score[j + 1] = temp;  
                }  
            }      
}

5.3 算法分析

  1. 时间复杂度:O(N*N)
  2. 空间复杂度:O(1)
  3. 稳定性:稳定

6.快速排序

6.1 算法思想

它是由冒泡排序改进而来的。在待排序的n个记录中任取一个记录(一般取第一个记录),把该记录放入适当位置后,数据序列被此记录划分红两部分。全部关键字比该记录关键字小的记录放置在前一部分,全部比它大的记录放置在后一部分,并把该记录排在这两部分的中间(称为该记录归位),这个过程称做一趟快速排序。ui

6.2 实现代码

public int getMiddle(Integer[] list, int low, int high) {  
        int tmp = list[low];    //数组的第一个做为中轴  
        while (low < high) {  
            while (low < high && list[high] > tmp) {  
                high--;  
            }  
            list[low] = list[high];   //比中轴小的记录移到低端  
            while (low < high && list[low] < tmp) {  
                low++;  
            }  
            list[high] = list[low];   //比中轴大的记录移到高端  
        }  
        list[low] = tmp;              //中轴记录到尾  
        return low;                   //返回中轴的位置  
    }
public void _quickSort(Integer[] list, int low, int high) {  
        if (low < high) {  
            int middle = getMiddle(list, low, high);  //将list数组进行一分为二  
            _quickSort(list, low, middle - 1);        //对低字表进行递归排序  
            _quickSort(list, middle + 1, high);       //对高字表进行递归排序  
        }  
    }

6.3 算法分析

  1. 时间复杂度:O(N*logN)
  2. 空间复杂度:O(N*logN)
  3. 稳定性:不稳定

(未完待续。。)spa

 

参考文献:

http://blog.csdn.net/wisgood/article/details/19702035.net

http://www.cnblogs.com/vanezkw/archive/2012/06/25/2561167.htmlcode

http://blog.csdn.net/gulianchao/article/details/8581210

http://www.cnblogs.com/e241138/archive/2012/10/17/2728633.html

http://blog.csdn.net/morewindows/article/details/6709644

http://blog.csdn.net/wangkuifeng0118/article/details/7286332

相关文章
相关标签/搜索