• 三种基础排序算法总结


    一、冒泡排序

    1、算法思想:

    1)、两层循环,外层循环i从0开始,内层循环从j=i+1开始
    2)、如果ary[i] < ary[j],则交换其值
    3)、直到外层循环到length-1

    2、主算法实现

    public static void bubbleSort(int[] ary){
        int length = ary.length;  
        //每完成一轮外层循环,ary[i]的次序在全局确定
        for (int i = 0; i < length; i++) {
            //内层循环向后扫描,且立即交换。
            for (int j = i+1; j < length; j++) {
                if (ary[i] > ary[j]) {
                    swap(ary, i, j);
                }
            }
        }
    }

    3、稳定性:

    int[] ary = {3,2,2,0};
    algoBubbleSort(ary);
    for(int value:ary){
        System.out.println(value);//{0,2,2,3},此冒泡排序是非稳定的排序
    }

    二、选择排序

    1、算法思想

    1)、两层循环,外层循环i从0开始,内层循环j从i+1开始。
    2)、用minIndex记录每轮内层循环的最小元素位置
    3)、每轮内层循环完成后交换ary[minIndex]和ary[i]的值

    2、主算法实现

        public static void selectionSort(int[] ary){
            int length = ary.length;
            int minIndex;
            //每完成一轮外层循环,ary[i]的次序在全局确定
            for (int i = 0; i < length; i++) {
                minIndex = i;
                for (int j = i+1; j < length; j++) {
                    if (ary[minIndex] > ary[j]) {//非立即交换,只更小元素的记录位置
                        minIndex = j;
                    }
                }
                //内层循环全部结束再交换
                swap(ary, i, minIndex);
            }
        }

    3、稳定性

    选择排序是非稳定的排序
    例如对数组{2,2,3,0}排序后,重复元素2的原有相对位置被破坏。

    三、插入排序

    1、算法思想

    1)、两层循环,外层循环i从0开始,内层循环j从i开始向前扫描
    2)、如果ary[j] < ary[j-1],也即元素ary[j]的值严格小于ary[j-1]的值,就立即交换。否则break停止j的扫描。

    2、算法实现

    1)版本一:O(n^2)的交换时间复杂度

        public static void insertSort(int[] ary){
            int length = ary.length;
            for (int i = 0; i < length; i++) {
                for (int j = i; j > 0; j--) {
                    //正确确定元素ary[j-1]的位置
                    //如果ary[j-1]严格大于ary[j],就将ary[j-1]向前挪动
                    if (ary[j] < ary[j-1]) {
                        swap(ary, j, j-1);
                    }else{
                        break;
                    }
                }
            }
        }

    2)版本二:

        public static void insertSort(int[] ary){
            int length = ary.length;
            int tmp,position;
            for (int i = 0; i < length; i++) {
                position = i;
                tmp = ary[i];
                for (int j = i; j > 0; j--) {
                    if (tmp < ary[j-1]) {
                        //挪动比tmp更大的元素,为tmp元素腾出位置。此时ary[j]和ary[j-1]相同
                        ary[j] = ary[j-1];
                        position = j-1;//更新其准确位置
                    }else{
                        break;
                    }
                    ary[position] = tmp;//正确放置ary[position]
                }
            }
        }

    3、稳定性:

    插入排序是稳定的排序。

    四、区别比较

    1、冒泡排序
    特点:内层循环j向后扫描,依次和ary[i]比较,遇到更小,则立即交换。
    每完成一轮外层循环,ary[i]在全局得到最终的次序,且ary[i]之前元素的次序也是全局的次序,后序的排序过程已对其不再有影响。

    2、选择排序
    特点:
    内层循环j同样向后扫描,依次和ary[i]比较,但是只记录更小元素的指针,最后才交换。
    每完成一轮外层循环,ary[i]在全局得到最终的次序,且ary[i]之前元素的次序也是全局的次序,后序的排序过程已对其不再有影响。


    3、插入排序
    特点:
    内层循环j向前扫描,依次和ary[i]比较,为ary[i]找到正确的位置。
    每完成一轮外层循环,ary[i]得到的次序只能是局部的次序,未必是全局的最终次序。同时ary[i]之前的元素只能是局部的次序,后序的排序过程可能会发生改变。

  • 相关阅读:
    面向对象:范式与思想
    每个人都应该懂点函数式编程
    Lambda 表达式-即匿名函数----Lambda演算-即匿名函数的等价推演过程-- => define as
    Side effect (computer science)
    系统理论
    参量与变量、指针、函数、对象
    面向对象和结构化程序设计的区别X
    面向对象编程与面向过程编程的区别(翻译版)
    2015 Objective-C 新特性
    Comparison of programming paradigms
  • 原文地址:https://www.cnblogs.com/qcblog/p/7532170.html
Copyright © 2020-2023  润新知