zoukankan      html  css  js  c++  java
  • 简单排序算法 冒泡排序 选择排序 插入排序

    冒泡排序:

      总体思路:对未排序的各个元素,依次比较两个元素,如果这两个元素为逆序(与想要的顺序相反),则交换这两个元素。

    这样可以有两种排序的思路:

    思路一:

      固定位置排序:比如有一个未排序队列,下标依次为0,1,2,.....N-1,

          第一轮排序:首先固定位置0,将下标为0的元素依次和下标为1、下标为2、....下标为N-1的元素相比较,若相比较的两个元素为逆序,则交换这两个元素,这样第一轮排序完之后,位置为0的元素,就是最大的(最小的)。

      第二轮排序:首先固定位置1,将下标为1的元素依次和下标为2、下标为3、....下标为N-1的元素相比较,若相比较的两个元素为逆序,则交换这两个元素,这样第二轮排序完之后,位置为1的元素,就是第二大的(第二小的)。

         ...

      第i轮排序(i<N-1):首先固定位置i,将下标为i的元素依次和下标为i+1、下标为i+2、....下标为N-1的元素相比较,若相比较的两个元素为逆序,则交换这两个元素,这样第i轮排序完之后,位置为i的元素,就是第i+1大的(第i+1小的)。

      第N-1轮排序:首先固定位置N-2,将下标为N-2的元素和下标为N-1的元素相比较,若相比较的两个元素为逆序,则交换这两个元素,这样第N-1轮排序完之后,位置为N-2的元素,就是第N-1大的(第N-1小的)。

         这样经过N-1轮排序之后,各个位置的元素都是已经排好序了的。

         固定位置排序代码演示如下:

      

    import java.util.Arrays;
    public class BubboleSort {
        public static void main(String[] args) {
            BubboleSort bs = new BubboleSort();
            int[] array = {2,5,1,3,9,8,0,4,6};
            System.out.println(Arrays.toString(array));
            bs.bubbleSort(array);
            System.out.println(Arrays.toString(array));
        }
    
        public void bubbleSort(int[] array){
            //外层取出一个用来比较的位置,当位置i确定之后,内层循环进行完之后,该位置的元素就确定了
            for (int i = 0; i < array.length; i++) {
                //内层循环依次取出需要进行比较的数据
                for (int j = i+1; j < array.length; j++) {
                    if (array[i] > array[j]) {
                        swap(array,i,j);
                    }
                }
            }
        }
       //交换数组中位置i和位置j的元素
        public void swap(int[] array,int i,int j){
            array[i] = array[i]^array[j];
            array[j] = array[i]^array[j];
            array[i] = array[i]^array[j];
        }
    }

    控制台输出:

    [2, 5, 1, 3, 9, 8, 0, 4, 6]
    [0, 1, 2, 3, 4, 5, 6, 8, 9]

    思路二:

      相邻元素比较:将相邻的两个元素依次进行比较,如果这两个元素逆序,则进行交换。比如有一个未排序队列,下标依次为0,1,2,.....N-1,

      第一轮排序:

        将下标为0的元素和下标为1的元素进行比较,若逆序,则交换;

           再将下标为1的元素和下标为2的元素进行比较,若逆序,则交换;

        再将下标为2的元素和下标为3的元素进行比较,若逆序,则交换;

        ...

        将下标为i(i<N-2)的元素和下标为i+1的元素进行比较,若逆序,则交换;

        最后将下标为N-2的元素和下标为N-1的元素进行比较,若逆序,则交换。

      这样,经过第一轮排序之后,最大(最小)的元素,就排在最后面了(下标为N-1),即队列最后的元素是排好序的,下一轮排序不用再排序了。

        第二轮排序:

        将下标为0的元素和下标为1的元素进行比较,若逆序,则交换;

           再将下标为1的元素和下标为2的元素进行比较,若逆序,则交换;

        再将下标为2的元素和下标为3的元素进行比较,若逆序,则交换;

        ...

        将下标为i(i<N-3)的元素和下标为i+1的元素进行比较,若逆序,则交换;

        最后将下标为N-3的元素和下标为N-2的元素进行比较,若逆序,则交换。

      这样,经过第二轮排序之后,最二大(最二小)的元素,就排在最后面了(下标为N-2),即下标为N-2的元素是排好序的,下一轮排序不用再排序了。

         重复上面的排序思路即可将剩余的元素全部排好顺序。

    代码演示如下:

    import java.util.Arrays;
    public class BubboleSort {
        public static void main(String[] args) {
            BubboleSort bs = new BubboleSort();
            int[] array = {2,5,1,3,9,8,0,4,6};
            System.out.println(Arrays.toString(array));
            bs.bubbleSort(array);
            System.out.println(Arrays.toString(array));
    
        }
        //相邻元素进行比较排序
        public void bubbleSort(int[] array){
            //i用来控制比较的次数
            for (int i = array.length -1; i > 0 ; i--) {
                //内层循环完成之后,表示一轮冒泡完成
                for (int j = 0; j < i; j++) {
                    if (array[j] > array[j+1]) {
                        swap(array,j,j+1);
                    }
                }
            }
        }
        //交换数组中位置i和位置j的元素
        public void swap(int[] array,int i,int j){
            array[i] = array[i]^array[j];
            array[j] = array[i]^array[j];
            array[i] = array[i]^array[j];
        }
       
    }

     控制台输出:

    [2, 5, 1, 3, 9, 8, 0, 4, 6]
    [0, 1, 2, 3, 4, 5, 6, 8, 9]

    冒泡排序性能:比较和交换的次数为 O(n2)

    选择排序:

      假设有一个待排序的数组array,下标依次为0,1,2,3,....N-1

      第一轮排序:从所有元素中选择一个最小(最大)值array[i],放在array[0]位置(即让array[i]与array[0]交换)。

      第二轮排序:从array[1]开始,找出一个最小(最大)值array[j],放在array[1]位置。

      ...

      N个数,要进行N-1轮排序。

      下面是代码演示:

    import java.util.Arrays;
    
    public class SelectSort {
        public static void main(String[] args) {
            SelectSort ss = new SelectSort();
            int[] array = {2,5,1,3,9,8,0,4,6};
            System.out.println(Arrays.toString(array));
            ss.selectSort(array);
            System.out.println(Arrays.toString(array));
        }
        public void selectSort(int[] array){
            for (int i = 0; i < array.length; i++) {
                int minIndex = i;
                for (int j = i+1; j < array.length; j++) {
                    //只记录位置,暂时不交换
                    if (array[minIndex] > array[j]) {
                        minIndex = j;
                    }
                }
                //经过内层循环之后,找到了该轮外层循环的位置i的要交换的最小值的位置minIndex,交换,若i== minIndex,说明位置i所在的元素,就是该轮比较的最小值了,所以不用交换了
                if (i != minIndex) {
                    swap(array,i,minIndex);
                }
            }
        }
    
        public void swap(int[] array,int i,int j){
            array[i] = array[i]^array[j];
            array[j] = array[i]^array[j];
            array[i] = array[i]^array[j];
        }
    }

    控制台输出:

    [2, 5, 1, 3, 9, 8, 0, 4, 6]
    [0, 1, 2, 3, 4, 5, 6, 8, 9]

    选择排序效率:比较次数为O(n²),交换的次数为O(n)

     插入法排序:

    基本思路:(设数组为升序) 每拿到一个元素,都要将这个元素依次与它之前的元素进行比较,若前面的元素比该元素大,则将前面的元素往后移动;直到前面的元素(设下标为i)比该元素小,则下标为i+1,就是该元素要插入的位置,插入即可
    代码演示如下:
    package com.lewis.sort.simpleSort;
    
    
    import java.util.Arrays;
    
    public class InsertSort {
        public static void main(String[] args) {
            InsertSort is = new InsertSort();
            int[] array = {2, 5, 1, 3, 0,9,-1, 8, 7, 4, 6};
            System.out.println(Arrays.toString(array));
            is.sort(array);
            System.out.println(Arrays.toString(array));
        }
    
        /**
         * 插入法排序:通过构建有序数列,将未排序的元素,从后往前依次比较,进而找到要插入的位置并插入
         * @param array
         */
        public void sort(int[] array){
            int j = 0;
            //假设数组中的第一个元素是已经排好序的
            //外层循环 表示待排序的元素
            for (int i = 1; i < array.length; i++) {
                //待排序的元素tmpData,要找到一个合适的位置插入
                int tmpData = array[i];
                //内层循环从待排序元素tmpData开始,依次往前扫描
                for (j = i; j > 0 ; j--) {
                    //将待排序元素tmpData依次和前面的元素比较, 若前面的元素比待排序的元素tmpData大,则将前面的元素依次往后移动
                    if (array[j - 1] > tmpData) {
                        array[j] = array[j-1];
                    }
                    else{
                        //说明前面已经是排好顺序了
                        break;
                    }
                }
                //内层循环结束之后,位置j就是待排序元素要插入的位置
                array[j] = tmpData;
            }
        }
    
    }

    控制台输出:

    [2, 5, 1, 3, 0, 9, -1, 8, 7, 4, 6]
    [-1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

    插入法排序效率:比较和交换次数都为 O(n²),但是比冒泡算法大约快一倍左右,比选择排序稍快,尤其是部分数据局部有序的情况下,插入法排序效率会更高

  • 相关阅读:
    常见apache问题
    机器学习——SVM讲解
    剑指offer——05用两个栈实现队列(Python3)
    剑指offer——04重建二叉树(Python3)
    剑指offer——03从尾至头打印列表(Python3)
    剑指offer——02替换空格(Python3)
    剑指offer——01二维数组中的查找(Python3)
    剑指offer——06旋转数组的最小数字(Python3)
    一个Python项目的创建架构
    python中各项目文件含义(新手可看)
  • 原文地址:https://www.cnblogs.com/lewis0077/p/5126492.html
Copyright © 2011-2022 走看看