排序算法

快速排序
快速排序使用分治法来把一个串(list)分为两个子串(sub-lists)。具体算法描述如下:
从数列中挑出一个元素,称为 “基准”(pivot);
重新排序数列,所有元素比基准值小的摆放在基准前面,所有元素比基准值大的摆在基准的后面(相同的数可以到任一边)。在这个分区退出之后,该基准就处于数列的中间位置。这个称为分区(partition)操作;
递归地(recursive)把小于基准值元素的子数列和大于基准值元素的子数列排序。
动图演示

代码实现

  public static void quickSort(int[] arr,int left,int right){
        int l = left; //左下标
        int r = right; //右下标
        //pivot 中轴值
        int pivot = arr[(left + right) / 2];
        int temp = 0;//临时变量 作为交换时使用
        //while 循环目的是让比pivot 值小的放到左边
        //比 pivot大的放右边
        while ( l < r){
            //在pivot左边一直找 直到找到比pivot大的值 就退出
            while (arr[l] < pivot){
                l += 1;
            }
            //在pivot右边一直找 直到找到比pivot小的值 就退出
            while (arr[r] > pivot){
                r -= 1;
            }
            //如果 l>=r 说明pivot 的左右值 已经按照左边全部是 小于等于pivot值。右边全部是 大于等于pivot值
            if(l >= r){
                break;
            }
            //交换
            temp = arr[l];
            arr[l] = arr[r];
            arr[r] = temp;

            //交换完成后 发现arr[l] == pivot相等 --,前移
            if(arr[l] == pivot){
                r -= 1;
            }
            //交换完成后 发现arr[r] == pivot相等 ++,后移
            if(arr[r] == pivot){
                l += 1;
            }
        }
        //如果 l == r 必须l++ , r-- ,否则就会栈溢出
        if(l==r){
            l += 1;
            r -= 1;
        }
        //向左递归
        if(left < r){
            quickSort(arr,left,r);
        }
        //向右递归
        if(right > l){
            quickSort(arr,l,right);
        }
    }

插入排序:
插入排序(Insertion-Sort)的算法描述是一种简单直观的排序算法。它的工作原理是通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入。

  1. 从第一个元素开始,该元素可以认为已经被排序;
  2. 取出下一个元素,在已经排序的元素序列中从后向前扫描;
  3. 如果该元素(已排序)大于新元素,将该元素移到下一位置;
  4. 重复步骤3,直到找到已排序的元素小于或者等于新元素的位置;
  5. 将新元素插入到该位置后;
  6. 重复步骤2~5。

动图演示

代码实现

    public static void insertSort(int[] arr){
        for (int i = 1; i < arr.length  ; i++) {
            int insertVal = arr[i];//要比较元素的位置
            int insertIndex = i - 1;//要比较的前一个元素
            
            //insertIndex >= 0 比较的前一个元素 防止下标越界
            //insertVal < arr[insertIndex] 如果要比较的元素 小于上个元素 就不用进入
            while (insertIndex >= 0 && insertVal < arr[insertIndex]){
                //如果要比较的元素 满足循环条件时 就将比较的元素替换为前一个元素
                //然后 --再找到替换后的前一个元素 进行比较 以此类推
                arr[insertIndex + 1] = arr[insertIndex];
                insertIndex --;
            }
            //比较完成后 循环条件不满足后 把比较的值替换了
            arr[insertIndex + 1] = insertVal;
        }
    }

选择排序:
选择排序(Selection-sort)是一种简单直观的排序算法。
它的工作原理:

  1. 首先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置。
  2. 然后,再从剩余未排序元素中继续寻找最小(大)元素。
  3. 然后放到已排序序列的末尾。以此类推,直到所有元素均排序完毕。

动图演示

代码实现

    public static void selectSort(int[] arr){
        for (int i = 0; i < arr.length - 1; i++) {
            int minIndex = i; //假定最小数下标
            int min = arr[i]; //假定最小值
            for (int j = i + 1; j < arr.length; j++) {
                //如果假定最小值 大于下一个比较的元素
                if(min > arr[j]){
                    min = arr[j]; //重置min 将小于假定最小值给替换
                    minIndex = j; //重置minIndex 将假定最小值下标也替换
                }
            }
            //如果最小值下标 就等于假定比较值 就说明假定的就是最小的 所以不用交换
            //如果不等于 就交换一下位置
            if(minIndex != i) {
                arr[minIndex] = arr[i];
                arr[i] = min;
            }
        }
    }

冒泡排序:

  1. 比较相邻的元素。如果第一个比第二个大,就交换他们两个。
  2. 对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对。这步做完后,最后的元素会是最大的数。
  3. 针对所有的元素重复以上的步骤,除了最后一个。
  4. 持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。

动图演示:

代码实现

    public static void bubbleSort(int[] arr){
        int temp = 0;
        //标识变量,表示是否交换过
        //优化冒泡 如果没有进行交换过 说明已经排序完成就不需要进行多余的比较了
        boolean flag = false;
        for (int i = 0; i < arr.length - 1; i++) {
            for (int j = 0; j < arr.length - 1 - i; j++) {
                if(arr[j] > arr[j+1]){
                    flag = true;
                    temp = arr[j];
                    arr[j] = arr[j+1];
                    arr[j+1] = temp;
                }
            }
            if(!flag){
                break; //如果没有交换过,说明已经排序完成
            } else{
                flag = false; //重置flag 进行下次判断
            }
        }
    }
posted @ 2022-03-28 20:50  橙香五花肉  阅读(19)  评论(0编辑  收藏  举报