zoukankan      html  css  js  c++  java
  • 数据结构-十大经典排序算法

    常见的内部排序算法有:插入排序、希尔排序、选择排序、冒泡排序、归并排序、快速排序、堆排序、基数排序等。用一张图概括:

     冒泡排序

      

    算法步骤

    比较相邻的元素。如果第一个比第二个大,就交换他们两个。

    对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对。这步做完后,最后的元素会是最大的数。

    针对所有的元素重复以上的步骤,除了最后一个。

    持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。

    Java 代码实现

    import java.util.Arrays;
    
    public class MaoPao {
        public static void main(String[] args){
            int[] arr = {1,45,43,12,91,4,66,82,19,213};
            arr = sort(arr);
            System.out.println(Arrays.toString(arr));
        }
        public static int[] sort(int[] sourceArray) {
            // 对 arr 进行拷贝,不改变参数内容
            int[] arr = Arrays.copyOf(sourceArray, sourceArray.length);
    
            for (int i = 1; i < arr.length; i++) {
                // 设定一个标记,若为true,则表示此次循环没有进行交换,也就是待排序列已经有序,排序已经完成。
                boolean flag = true;
    
                for (int j = 0; j < arr.length - i; j++) {
                    if (arr[j] > arr[j + 1]) {
                        int tmp = arr[j];
                        arr[j] = arr[j + 1];
                        arr[j + 1] = tmp;
    
                        flag = false;
                    }
                }
    
                if (flag) {
                    break;
                }
            }
            return arr;
        }
    }

    选择排序

      

    算法步骤

    首先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置。

    再从剩余未排序元素中继续寻找最小(大)元素,然后放到已排序序列的末尾。

    重复第二步,直到所有元素均排序完毕。

    Java 代码实现

    import java.util.Arrays;
    
    public class XuanZe {
        public static void main(String[] args) {
            int[] arr = {1,45,43,12,91,4,66,82,19,213};
            arr = sort(arr);
            System.out.println(Arrays.toString(arr));
        }
    
        public static int[] sort(int[] sourceArray){
            int[] arr = Arrays.copyOf(sourceArray, sourceArray.length);
    
            // 总共要经过 N-1 轮比较
            for (int i = 0; i < arr.length - 1; i++) {
                int min = i;
    
                // 每轮需要比较的次数 N-i
                for (int j = i + 1; j < arr.length; j++) {
                    if (arr[j] < arr[min]) {
                        // 记录目前能找到的最小值元素的下标
                        min = j;
                    }
                }
    
                // 将找到的最小值和i位置所在的值进行交换
                if (i != min) {
                    int tmp = arr[i];
                    arr[i] = arr[min];
                    arr[min] = tmp;
                }
    
            }
            return arr;
        }
    }
    

      

    插入排序

    算法步骤

    将第一待排序序列第一个元素看做一个有序序列,把第二个元素到最后一个元素当成是未排序序列。

    从头到尾依次扫描未排序序列,将扫描到的每个元素插入有序序列的适当位置。(如果待插入的元素与有序序列中的某个元素相等,则将待插入元素插入到相等元素的后面。)

    Java 代码实现

    import java.util.Arrays;
    
    public class ChaRu {
        public static void main(String[] args) {
            int[] arr = {1,45,43,12,91,4,66,82,19,213};
            arr = sort(arr);
            System.out.println(Arrays.toString(arr));
        }
    
        public static int[] sort(int[] sourceArray){
            // 对 arr 进行拷贝,不改变参数内容
            int[] arr = Arrays.copyOf(sourceArray, sourceArray.length);
    
            // 从下标为1的元素开始选择合适的位置插入,因为下标为0的只有一个元素,默认是有序的
            for (int i = 1; i < arr.length; i++) {
    
                // 记录要插入的数据
                int tmp = arr[i];
    
                // 从已经排序的序列最右边的开始比较,找到比其小的数
                int j = i;
                while (j > 0 && tmp < arr[j - 1]) {
                    arr[j] = arr[j - 1];
                    j--;
                }
    
                // 存在比其小的数,插入
                if (j != i) {
                    arr[j] = tmp;
                }
    
            }
            return arr;
        }
    }
    

      

    快速排序

    算法步骤

    1. 从数列中挑出一个元素,称为 "基准"(pivot);

    2. 重新排序数列,所有元素比基准值小的摆放在基准前面,所有元素比基准值大的摆在基准的后面(相同的数可以到任一边)。在这个分区退出之后,该基准就处于数列的中间位置。这个称为分区(partition)操作;

    3. 递归地(recursive)把小于基准值元素的子数列和大于基准值元素的子数列排序;

     

    Java 代码实现

    import java.util.Arrays;
    
    public class KuaiSu {
        public static void main(String[] args) {
            int[] arr = {1,45,43,12,91,4,66,82,19,213};
            arr = sort(arr);
            System.out.println(Arrays.toString(arr));
        }
    
        public static int[] sort(int[] sourceArray){
            // 对 arr 进行拷贝,不改变参数内容
            int[] arr = Arrays.copyOf(sourceArray, sourceArray.length);
            return quickSort(arr, 0, arr.length - 1);
        }
    
        private static int[] quickSort(int[] arr, int left, int right) {
            if (left < right) {
                int partitionIndex = partition(arr, left, right);
                quickSort(arr, left, partitionIndex - 1);
                quickSort(arr, partitionIndex + 1, right);
            }
            return arr;
        }
    
        private static int partition(int[] arr, int left, int right) {
            // 设定基准值(pivot)
            int pivot = left;
            int index = pivot + 1;
            for (int i = index; i <= right; i++) {
                if (arr[i] < arr[pivot]) {
                    swap(arr, i, index);
                    index++;
                }
            }
            swap(arr, pivot, index - 1);
            return index - 1;
        }
    
        private static void swap(int[] arr, int i, int j) {
            int temp = arr[i];
            arr[i] = arr[j];
            arr[j] = temp;
        }
    
    }
    

      

  • 相关阅读:
    产生WM_PAINT 消息
    模板作为模板的参数
    转:网络游戏同步原理荟萃
    一个隐晦的c++语法问题
    Winbind authentication against active directory
    In Place Upgrade of CentOS 6 to CentOS 7
    How To mount/Browse Windows Shares【在linux{centos}上挂载、浏览window共享】
    File System Shell
    Administration Commands
    User Commands
  • 原文地址:https://www.cnblogs.com/ning-blogs/p/11025484.html
Copyright © 2011-2022 走看看