常见排序算法

定义

假设含有n个记录的序列为{r1​,r2​,…,rn​},其相应的关键字分别为{k1​,k2​,…,kn​},需确定1,2, 3, …, n的一种排列p1​,p2​,…,pn​,使其相应的关键字满足kp1​ ≤kp2​≤…≤kpn​非递减(或非递增)关系,即使得序列变成一个按关键字有序的序列{rp1​,rp2​,…,rpn​}

让[1, 2, 32, 23, 321, 45, 8, 90, 227, 99]从小到大排列

常见排序

  • 冒泡排序
    先拿第1第2个数比较,谁大谁后面,接着第2个跟第3个,继续...,最后的那个数一定是最大的。接下来混乱的序列就少了一位,继续剩下的序列继续上面的一轮。这个过程就像一个波浪一次把最大值从前面推到后面
public static void main(String[] args) {
        // TODO Auto-generated method stub
        int []arr= {1, 2, 32, 23, 321, 45, 8, 90, 227, 99};
        for(int i=0;i<arr.length-1;i++) {
            for(int j=0;j<arr.length-i-1;j++) {
                if(arr[j]>arr[j+1]) {
                    int temp=arr[j];
                    arr[j]=arr[j+1];
                    arr[j+1]=temp;
                }
            }
        }
        for(int a:arr) {
            System.out.print(a+" ");
        }
    }
    
    //1 2 8 23 32 45 90 99 227 321 
  • 选择排序
    冒泡排序每次比较后符合要求的都去交换,有些处于中间值的,不是要不断的被交换,不是很浪费时间?能不能选出这段序列中最大的那个数,然后放到最后边? 这就是选择排序。
public static void main(String[] args) {
        int []arr= {1, 2, 32, 23, 321, 45, 8, 90, 227, 99};
        for(int i=0;i<arr.length-1;i++) {
            int k=i;
            //位置还不确定的数据
            for(int j=i+1;j<arr.length;j++) {
                if(arr[j]<arr[k]) {
                    k=j;
                    //遍历找到比k小的索引,然后把j赋给k;
                }
            }
            if(i!=k) {
                int temp=arr[i];
                arr[i]=arr[k];
                arr[k]=temp;
            }
        }
        for(int a:arr) {
            System.out.print(a+" ");
        }
    }
    //1 2 8 23 32 45 90 99 227 321 
  • 插入排序
    举个例子,假设现在桌面有几张牌,每次拿起一张,我们在排序的时候会很自然的将牌按照顺序插入合适的位置。这个思想就是插入排序。
  public static void insertSort(int[] arr) {
        int j = 0;
        for (int i = 1; i < arr.length; i++) {
            int temp = arr[i];//要插入的值,i位置空出来了
            for (j = i; j > 0 && arr[j - 1] > temp; j--) {
                arr[j] = arr[j - 1];//j-1 扔到空出来的位置
            }
            arr[j] = temp;//temp 扔到空出来的位置
        }
    }
     //1 2 8 23 32 45 90 99 227 321 
  • 希尔排序
    希尔排序排序是插入排序的改进算法,实现原理是将整个无序列分割成若干小的子序列分别进行插入排序,希尔排序并不稳定。该方法又称缩小增量排序。
 public static void shellSort(int[] a) {
        int dk;//步长
        for (dk = a.length / 2; dk > 0; dk /= 2) {
            for (int i = dk; i < a.length; i++) {
                int temp = a[i];//要插入的值,i位置空出来了
                int j;
                for (j = i; j >= dk && temp < a[j - dk]; j -= dk)//步长为dk的插入排序
                    a[i] = a[j - dk]; //j - dk 扔到空出来的位置
                a[j] = temp;//temp 扔到空出来的位置
            }
        }
    }
    //1 2 8 23 32 45 90 99 227 321 
  • 归并排序
    将带排序序列分成小组,每个小组自己先弄成有序的,再汇总,这样这种分而治之思想的实际上就是归并排序。
    public static void mergerSort(int arr[], int low, int high) {
        int mid = (low + high) >> 1;
        if (low < high) {
            mergerSort(arr, low, mid);
            mergerSort(arr, mid + 1, high);
            merger(arr, low, mid, high);
        }

    }

    public static void merger(int arr[], int low, int mid, int high) {
        int temp[] = new int[high - low + 1]; //临时数组
        int t = 0;//临时数组的首索引
        int first = low;//第一个数组的首索引
        int second = mid + 1;//第二个数组的首索引

        // 将练个有序数组比较插入临时数组
        while (first <= mid && second <= high) {
            temp[t++] = arr[first] < arr[second] ? arr[first++] : arr[second++];
        }

        //  将数组剩余部分接到临时数组尾部
        while (first <= mid) {
            temp[t++] = arr[first++];
        }
        while (second <= high) {
            temp[t++] = arr[second++];
        }

        //    将临时数据合并到原始数组
        for (int i = 0; i < temp.length; i++) {
            arr[i + low] = temp[i];
        }
    }
    //1 2 8 10 23 32 45 90 99 227 321 
  • 快速排序
    举个例子:上体育课的时候要高个子站后面矮个子站前面,教练没办法一开始就一眼看出谁高谁矮对,那么多人,肯定是随便逮一个逮个人,来以他为基准进行排序。要求小个子的站这人的前边,大个子的站后边。
    而这就是快速排序的核心思想。
 public static void quickSort(int arr[], int low, int high) {
        if (low < high) {
            int index = part(arr, low, high);
            quickSort(arr, low, index - 1);
            quickSort(arr, index + 1, high);

        }
    }
    
    public static int part(int arr[], int low, int high) {
        int s1=low,s2=high;//定义哨兵
        int key = arr[low];
        while (s1 < s2) {
            while (s1 < s2 && (arr[s2] >= key)) {//哨兵2 向左巡逻 查找小于key的位置 停下
                s2--;
            }
            swap(arr,s1, s2);
            while (s1 < s2 && arr[s1] <= key) {//哨兵1 向右巡逻 查找大于key的位置  停下
                s1++;
            }
            swap(arr, s1, s2);
        }
        return s1;

    }

    public static void swap(int arr[], int s1, int s2) {

        int temp = arr[s1];
        arr[s1] = arr[s2];
        arr[s2] = temp;
    }
//1 2 2 6 8 10 23 32 45 90 99 321 
原文地址:https://www.cnblogs.com/lillcol/p/11171994.html