Java数据结构的十大排序

目录
  • 1.直接插入排序
    • 1.1 动图演示
    • 1.2 插入排序的思路
    • 1.3 代码实现
    • 1.4 性能分析
  • 2.希尔排序
    • 2.1 原理
    • 2.2 动图演示
    • 2.3 代码实现
    • 2.4 性能分析
  • 3.直接选择排序
    • 3.1 动图演示
    • 3.2 代码实现
    • 3.3 性能分析
  • 4.堆排序
    • 4.1 动图演示
    • 4.2 代码实现
    • 4.3 性能分析
  • 5.冒泡排序
    • 5.1 动图演示
    • 5.2 代码实现
    • 5.3 性能分析
  • 6.快速排序
    • 6.1 原理
    • 6.2 动图演示
    • 6.3 实现方法
      • 6.3.1 Hoare法
      • 6.3.2 挖坑法
    • 6.4 代码实现
    • 6.5 快排优化
      • 6.5.1 三数取中法
      • 6.5.2 加上直接插入排序
    • 6.6 非递归的实现
      • 6.6.1 非递归思路
      • 6.6.2 非递归代码实现
    • 6.7 性能分析
  • 7.归并排序
    • 7.1 原理
    • 7.2 动图演示
    • 7.3 代码实现—递归
    • 7.4 代码实现—非递归
    • 7.5 性能分析
  • 8.计数排序
    • 8.1 算法的步骤
    • 8.2 动图演示
    • 8.3 代码实现
    • 8.4 性能分析
  • 9.桶排序
    • 9.1 原理
    • 9.2 算法的步骤
    • 9.3 画图解析
    • 9.4 代码实现
    • 9.5 性能分析
  • 10.基数排序
    • 10.1 算法的步骤
    • 10.2 动图演示
    • 10.3 代码实现
    • 10.4 性能分析

1.直接插入排序

1.1 动图演示

1.2 插入排序的思路

  1. 从第一个元素开始,这里我们第一个元素是已排序的.
  2. 取下一个元素,和有序序列的元素从后往前比较.( 有序区间 : [0,i) )
  3. 如果得到的有序序列的元素 比 该元素大 则 将取得的有序元素往后放
  4. 重复3操作,直到得到的有序元素 比 该元素小, 或者 有序元素比完了.记录这个位置
  5. 然后将该元素放入到这个位置.
  6. 遍历数组,重复2~5的操作.

1.3 代码实现

   /**
     * 时间复杂度:
     *      最好的情况: O(n)
     *      最坏的情况: O(n^2)
     * 空间复杂度: O(1)
     * @param array
     */
    public static void insertSort(int[] array) {
        for (int i = 1; i < array.length; i++) {
            int j = i - 1;
            int tmp = array[i];
            while (j >= 0) {
                if (array[j] > tmp) {
                    array[j + 1] = array[j];
                    j--;
                }else {
                    break;
                }
            }
            array[j + 1] = tmp;
        }
    }

1.4 性能分析

时间复杂度(平均) 时间复杂度(最坏) 时间复杂度(最好) 空间复杂度 稳定性
O(n^2) O(n^2) O(n) O(1) 稳定

插入排序,初始数据越接近有序,时间效率越高。

2.希尔排序

2.1 原理

希尔排序法又称缩小增量法。希尔排序法的基本思想是:先选定一个整数gap,把待排序文件中所有记录分成个gap组,所有距离为gap的记录分在同一组内,并对每一组内的记录进行排序。然后,取gap = (gap/3)+1,重复上述分组和排序的工作。当到达gap=1时,所有记录在统一组内排好序。

  • 希尔排序是对直接插入排序的优化。
  • 当gap > 1时都是预排序,目的是让数组更接近于有序。当gap == 1时,数组已经接近有序的了,这样就会很快。这样整体而言,可以达到优化的效果。我们实现后可以进行性能测试的对比。

2.2 动图演示

2.3 代码实现

    /**
     *
      * @param array 排序的数组
     * @param gap 每组的间隔 -> 数组
     */
     public static void shell(int[] array,int gap){
         for (int i = gap; i < array.length ; i++) {
             int tmp = array[i];
             int j = i - gap;
             while(j>=0){
                 if(array[j] > tmp){
                     array[j + gap] = array[j];
                     j -= gap;
                 }else {
                     break;
                 }
             }
             array[j + gap] = tmp;
         }
     }

     public static void shellSort(int[] array){
         int gap = array.length;
         while (gap > 1){
             gap = (gap / 3) + 1;// +1 保证最后一个序列是 1 (除几都行)
             shell(array,gap);
         }
     }

2.4 性能分析

时间复杂度(平均) 时间复杂度(最坏) 时间复杂度(最好) 空间复杂度 稳定性
O(n^1.3) O(n^2) O(n) O(1) 不稳定

3.直接选择排序

3.1 动图演示

3.2 代码实现

 /**
     * 时间复杂度:
     *      最好: O(n^2)
     *      最坏: O(n^2)
     * 空间复杂度: O(1)
     * 稳定性: 不稳定
     * @param array
     */
    public static void selectSort(int[] array){
        for (int i = 0; i < array.length - 1; i++) {
            for (int j = i + 1; j <array.length ; j++) {
                if(array[j] < array[i]){
                    int tmp = array[i];
                    array[i] = array[j];
                    array[j] = tmp;
                }
            }
        }
    }

3.3 性能分析

时间复杂度(平均) 时间复杂度(最坏) 时间复杂度(最好) 空间复杂度 稳定性
O(n^2) O(n^2) O(n^2) O(1) 不稳定

4.堆排序

4.1 动图演示

4.2 代码实现

    public static void siftDown(int[] array,int root, int len){
        int parent = root;
        int child = root * 2 + 1;
        while (child < len){
            if( child+1 < len && array[child] < array[child+1] ){
                child++;
            }
            //这里child下标就是左右孩子的最大值的下标
            if(array[child] > array[parent]){
                int tmp = array[child];
                array[child] = array[parent];
                array[parent] = tmp;
                parent = child;
                child = parent * 2 + 1;
            }else {
                break;
            }
        }
    }

    public static void createHeap(int[] array){
        for (int i = (array.length - 1 - 1) / 2; i >= 0; i++) {
            siftDown(array,i,array.length);
        }
    }
    public static void heapSort(int[] array){
        createHeap(array);
        int end = array.length - 1;
        while (end > 0){
            int tmp = array[end];
            array[end] = array[0];
            array[0] =tmp;
            siftDown(array,0,end);
            end--;
        }
    }

4.3 性能分析

时间复杂度(平均) 时间复杂度(最坏) 时间复杂度(最好) 空间复杂度 稳定性
O(n * log(n)) O(n * log(n)) O(n * log(n)) O(1) 不稳定

5.冒泡排序

5.1 动图演示

5.2 代码实现

public static void BubbleSort(int[] array){
        for (int i = 0; i < array.length - 1; i++) {
            boolean flg = false;
            for (int j = 0; j < array.length - 1 - i ; j++) {
                if(array[j+1] < array[j]){
                    int tmp = array[j];
                    array[j] = array[j+1];
                    array[j+1] = tmp;
                    flg = true;
                }
            }
            if(!flg){
                break;
            }
        }
    }

5.3 性能分析

时间复杂度(平均) 时间复杂度(最坏) 时间复杂度(最好) 空间复杂度 稳定性
O(n^2) O(n^2) O(n) O(1) 稳定

6.快速排序

6.1 原理

  • 从待排序区间选择一个数,作为基准值(pivot);
  • Partition: 遍历整个待排序区间,将比基准值小的(可以包含相等的)放到基准值的左边,将比基准值大的(可以包含相等的)放到基准值的右边;
  • 采用分治思想,对左右两个小区间按照同样的方式处理,直到小区间的长度 == 1,代表已经有序,或者小区间的长度 == 0,代表没有数据。

6.2 动图演示

6.3 实现方法

6.3.1 Hoare法

6.3.2 挖坑法

6.4 代码实现

  //Hoare法
    public static void swap(int[] array,int i,int j){
        int tmp = array[i];
        array[i] = array[j];
        array[j] = tmp;
    }
    public static int partition1(int[] array,int low,int high) {
        int i = low;
        int tmp = array[low];
        while (low < high){
            while (low < high && array[high] >= tmp){
                high--;
            }
            while (low < high && array[low] <= tmp){
                low++;
            }
            swap(array,low,high);
        }
        swap(array,i,low);
        return low;
    }

    //挖坑法
    public static int partition2(int[] array,int low,int high) {
        int tmp = array[low];

        while (low < high){
            while (low < high && array[high] >= tmp){
                high--;
            }
            array[low] = array[high];
            while (low < high && array[low] <= tmp){
                low++;
            }
            array[high] = array[low];
        }
        array[low] = tmp;
        return low;
    }

    public static void quick(int[] array,int start,int end){
        if(start >= end) return;
        int pivot = partition1(array,start,end);

        quick(array,start,pivot-1);

        quick(array,pivot+1,end);
    }
    public static void quickSort(int[] array){
        quick(array,0,array.length-1);
    }

6.5 快排优化

6.5.1 三数取中法

   public static void swap(int[] array,int i,int j){
        int tmp = array[i];
        array[i] = array[j];
        array[j] = tmp;
    }
        public static int partition2(int[] array,int low,int high) {
        int tmp = array[low];

        while (low < high){
            while (low < high && array[high] >= tmp){
                high--;
            }
            array[low] = array[high];
            while (low < high && array[low] <= tmp){
                low++;
            }
            array[high] = array[low];
        }
        array[low] = tmp;
        return low;
    }
    public static void selectPivotMedianOFThree(int[] array,int start,int end,int mid){
        if(array[mid] > array[start]){
            swap(array,start,mid);
        }//此时mid下标的值肯定小于start下标的值 array[mid] <= array[start]
        if(array[mid] > array[end]){
            swap(array,mid,end);
        }//此时mid下标的值肯定小于end下标的值 array[mid] <= array[end]
        if(array[start] > array[end]){
            swap(array,start,end);
        }//此时有 array[mid] <= array[start] <= array[end]
    }

    public static void quick1(int[] array,int start,int end){
        if(start >= end) return;
        int mid = (start + end) / 2;
        selectPivotMedianOFThree(array,start,end,mid);

        int pivot = partition2(array,start,end);

        quick1(array,start,pivot-1);

        quick1(array,pivot+1,end);
    }

    public static void quick1Sort(int[] array){
        quick1(array,0,array.length - 1);
    }

6.5.2 加上直接插入排序

    public static void swap(int[] array,int i,int j){
        int tmp = array[i];
        array[i] = array[j];
        array[j] = tmp;
    }
    public static void insertSort2(int[] array,int start,int end){
        for (int i = start + 1; i <= end; i++) {
            int j = i + 1;
            int tmp = array[i];
            while (j >= 0){
                if(array[j] > tmp){
                    array[j+1] = array[j];
                }else {
                    break;
                }
            }
            array[j+1] = tmp;
        }
    }
        public static int partition2(int[] array,int low,int high) {
        int tmp = array[low];

        while (low < high){
            while (low < high && array[high] >= tmp){
                high--;
            }
            array[low] = array[high];
            while (low < high && array[low] <= tmp){
                low++;
            }
            array[high] = array[low];
        }
        array[low] = tmp;
        return low;
    }
        public static void selectPivotMedianOFThree(int[] array,int start,int end,int mid){
        if(array[mid] > array[start]){
            swap(array,start,mid);
        }//此时mid下标的值肯定小于start下标的值 array[mid] <= array[start]
        if(array[mid] > array[end]){
            swap(array,mid,end);
        }//此时mid下标的值肯定小于end下标的值 array[mid] <= array[end]
        if(array[start] > array[end]){
            swap(array,start,end);
        }//此时有 array[mid] <= array[start] <= array[end]
    }

    public static void quick2(int[] array,int start,int end){
        if(start >= end) return;
        if(end - start + 1 <= 100){
            insertSort2(array,start,end);
            return;
        }
        int mid = (start + end)/2;
        selectPivotMedianOFThree(array,start,end,mid);

        int pivot = partition2(array,start,end);
        quick2(array,start,pivot-1);
        quick2(array,pivot+1,end);
    }    
    public static void quick2Sort(int[] array){
        quick2(array,0,array.length - 1);
    }

6.6 非递归的实现

6.6.1 非递归思路

  • 首先调用partition,找到pivot
  • 然后把pivot的 左区间 和 右区间 的下标放到栈立马
  • 判断栈是否为空,不为空,弹出栈顶的2个元素(注意:入栈的顺序 决定了出栈的顺序中的第一个元素是high的还是low的)
  • 然后再进行调用partition,找pivot,
  • 重复以上操作.

6.6.2 非递归代码实现

  public static void quickSort4(int[] array){
        Stack<Integer> stack = new Stack<>();
        int low = 0;
        int high = array.length - 1;

        int pivot = partition2(array,low ,high);
        //左边有2个元素即以上
        if(pivot > low + 1){
            stack.push(0);
            stack.push(pivot - 1);
        }
        //右边有2个元素即以上
        if(pivot < high - 1){
            stack.push(pivot + 1);
            stack.push(high);
        }
        while (!stack.isEmpty()){
            high = stack.pop();
            low = stack.pop();
            pivot = partition2(array,low,high);
            //左边有2个元素即以上
            if(pivot > low + 1){
                stack.push(0);
                stack.push(pivot - 1);
            }
            //右边有2个元素即以上
            if(pivot < high - 1){
                stack.push(pivot + 1);
                stack.push(high);
            }
        }
    }

6.7 性能分析

时间复杂度(平均) 时间复杂度(最坏) 时间复杂度(最好) 空间复杂度 稳定性
O(n * log(n)) O(n^2) O(n * log(n)) O(log(n))~O(n) 不稳定

7.归并排序

7.1 原理

归并排序(MERGE-SORT)是建立在归并操作上的一种有效的排序算法,该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子 序列段间有序。若将两个有序表合并成一个有序表,称为二路归并。

7.2 动图演示

7.3 代码实现—递归

    public static void merge(int[] array,int low ,int high ,int mid){
        int s1 = low;
        int e1 = mid;
        int s2 = mid+1;
        int e2 = high;

        int[] tmp = new int[high - low + 1];
        int k = 0;

        while (s1 <= e1 && s2 <= e2){
            if(array[s1] <= array[s2]){
                tmp[k++] = array[s1++];
            }else {
                tmp[k++] = array[s2++];
            }
        }
        while (s1 <= e1){
            tmp[k++] = array[s1++];
        }
        while (s2 <= e2){
            tmp[k++] = array[s2++];
        }

        for (int i = 0; i < tmp.length; i++) {
            array[i+low] = tmp[i];
        }
    }
    public static void mergeSortInternal(int[] array,int low ,int high){
        if(low >= high) return;
        int mid = (low + high) / 2;
        mergeSortInternal(array,low,mid);
        mergeSortInternal(array,mid+1,high);

        merge(array,low,high,mid);
    }

    public static void mergeSort(int[] array){
        mergeSortInternal(array,0,array.length - 1);
    }

7.4 代码实现—非递归

    public static void merge1(int[] array,int gap){
        int[] tmp = new int[array.length];
        int k = 0;

        int s1 = 0;
        int e1 = s1 + gap - 1;

        int s2 = e1 + 1;
        int e2 = s2 + gap - 1 > array.length ? array.length - 1 : s2 + gap - 1;

        while (s2 < array.length){
            while (s1 <= e1 && s2 <= e2){
                if(array[s1] <= array[s2]){
                    tmp[k++] = array[s1++];
                }else {
                    tmp[k++] = array[s2++];
                }
            }
            while (s1 <= e1){
                tmp[k++] = array[s1++];
            }
            while (s2 <= e2){
                tmp[k++] = array[s2++];
            }

            s1 = e2 + 1;
            e1 = s1 + gap - 1;

            s2 = e1 + 1;
            e2 = s2 + gap - 1 > array.length ? array.length - 1 : s2 + gap - 1;
        }

        while (s1 <= array.length - 1){
            tmp[k++] = array[s1++];
        }

        for (int i = 0; i < tmp.length; i++) {
            array[i] = tmp[i];
        }
    }

    public static void mergeSort1(int[] array){
        for (int i = 1; i < array.length; i*=2) {
            merge1(array,i);
        }
    }

7.5 性能分析

时间复杂度(平均) 时间复杂度(最坏) 时间复杂度(最好) 空间复杂度 稳定性
O(n * log(n)) O(n * log(n)) O(n * log(n)) O(n) 稳定

8.计数排序

当输入的元素是 n 个 0 到 k 之间的整数时,它的运行时间是 O(n + k)。计数排序不是比较排序,排序的速度快于任何比较排序算法。

8.1 算法的步骤

(1)找出待排序的数组中最大和最小的元素
(2)统计数组中每个值为i的元素出现的次数,存入数组C的第i项
(3)对所有的计数累加(从C中的第一个元素开始,每一项和前一项相加)
(4)反向填充目标数组:将每个元素i放在新数组的第C(i)项,每放一个元素就将C(i)减去1

8.2 动图演示

8.3 代码实现

    public static void CountingSort(int[] array){
        int maxValue = GetMaxValue(array);
        int bucketLen = maxValue + 1;
        int[] bucket = new int[bucketLen];
        for (int value:array) {
            bucket[value]++;
        }
        int index = 0 ;

        for (int i = 0; i < bucketLen; i++) {
            while(bucket[i] > 0){
                array[index++] = i;
                bucket[i]--;
            }
        }
    }

    public static int GetMaxValue(int[] array){
        int maxValue = array[0];
        for (int i = 0; i < array.length; i++) {
            if(maxValue < array[i]){
                maxValue = array[i];
            }
        }
        return maxValue;
    }

8.4 性能分析

时间复杂度(平均) 时间复杂度(最坏) 时间复杂度(最好) 空间复杂度 稳定性
O(n+k) O(n+k) O(n+k) O(k) 稳定

9.桶排序

9.1 原理

桶排序是计数排序的升级版。它利用了函数的映射关系,高效与否的关键就在于这个映射函数的确定。桶排序 (Bucket sort)的工作的原理:假设输入数据服从均匀分布,将数据分到有限数量的桶里,每个桶再分别排序(有可能再使用别的排序算法或是以递归方式继续使用桶排序进行排)。

为了使桶排序更加高效,我们需要做到这两点:

  • 在额外空间充足的情况下,尽量增大桶的数量
  • 使用的映射函数能够将输入的 N 个数据均匀的分配到 K 个桶中

同时,对于桶中元素的排序,选择何种比较排序算法对于性能的影响至关重要。

9.2 算法的步骤

  • 设置一个定量的数组当作空桶;
  • 遍历输入数据,并且把数据一个一个放到对应的桶里去;
  • 对每个不是空的桶进行排序;
  • 从不是空的桶里把排好序的数据拼接起来。

9.3 画图解析

9.4 代码实现

 public static void bucketSort(int[] arr) {
        if (arr.length == 0) {
            return;
        }

        int minValue = arr[0];
        int maxValue = arr[0];
        for (int value : arr) {
            if (value < minValue) {
                minValue = value;
            } else if (value > maxValue) {
                maxValue = value;
            }
        }
        //得到最大和最小元素

        int bucketNum = (maxValue - minValue) / arr.length + 1;//桶的数量
        ArrayList<ArrayList<Integer>> bucket = new ArrayList<>(bucketNum);
        for (int i = 0; i < bucketNum; i++) {
            bucket.add(new ArrayList<>());
        }
        
        //将元素放入到桶中
        for (int i = 0; i < arr.length; i++) {
            int num = (arr[i] - minValue) / arr.length;
            bucket.get(num).add(arr[i]);
        }

        for (int i = 0; i < bucket.size(); i++) {
            //这里是比较,可以选择其他的方式实现,这里为了演示采取Collection的sort
            Collections.sort(bucket.get(i));
        }

        // 将桶中的元素赋值到原序列
        int index = 0;
        for(int i = 0; i < bucket.size(); i++){
            for(int j = 0; j < bucket.get(i).size(); j++){
                arr[index++] = bucket.get(i).get(j);
            }
        }
    }

9.5 性能分析

时间复杂度(平均) 时间复杂度(最坏) 时间复杂度(最好) 空间复杂度 稳定性
O(n+k) O(n^2) O(n+k) O(n+k) 稳定

10.基数排序

10.1 算法的步骤

  • 取得数组中的最大数,并取得位数;
  • arr为原始数组,从最低位开始取每个位组成radix数组;
  • 对radix进行计数排序(利用计数排序适用于小范围数的特点)

10.2 动图演示

10.3 代码实现

    public static int getNumLength(int num){
        if(num == 0) return 1;
        int count = 0;
        for (int i = num; i != 0; i /= 10) {
            count++;
        }
        return count;
    }
    public static void RadixSort(int[] array){
        int maxValue = array[0];
        for (int i = 0; i < array.length; i++) {
            if(maxValue < array[i]){
                maxValue = array[i];
            }
        }
        int maxDigit = getNumLength(maxValue);

        int mod = 10;
        int dev = 1;
        for (int i = 0; i < maxDigit; i++, dev *= 10, mod *= 10) {
            int[][] counter = new int[mod * 2][0];

            for (int j = 0; j < array.length; j++) {
                int bucket = ((array[j] % mod) / dev) + mod;
                counter[bucket] = arrayAppend(counter[bucket], array[j]);
            }

            int pos = 0;
            for (int[] bucket : counter) {
                for (int value : bucket) {
                    array[pos++] = value;
                }
            }
        }

    }
    public static int[] arrayAppend(int[] arr, int value) {
        arr = Arrays.copyOf(arr, arr.length + 1);
        arr[arr.length - 1] = value;
        return arr;
    }

10.4 性能分析

时间复杂度(平均) 时间复杂度(最坏) 时间复杂度(最好) 空间复杂度 稳定性
O(n*k) O(n*2) O(n*k) O(n+k) 稳定

总结:

到此这篇关于 Java数据结构的十大排序的文章就介绍到这了,更多相关 Java数据结构十大排序内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • JAVA十大排序算法之希尔排序详解

    目录 希尔排序 代码实现 时间复杂度 算法稳定性 总结 希尔排序 一种基于插入排序的快速的排序算法.简单插入排序对于大规模乱序数组很慢,因为元素只能一点一点地从数组的一端移动到另一端.例如,如果主键最小的元素正好在数组的尽头,要将它挪到正确的位置就需要n-1次移动. 希尔排序为了加快速度简单地改进了插入排序,也称为缩小增量排序. 希尔排序是把待排序数组按一定的数量分组,对每组使用直接插入排序算法排序:然后缩小数量继续分组排序,随着数量逐渐减少,每组包含的元素越来越多,当数量减至 1 时,整个数组

  • java版十大排序经典算法:完整代码(4)

    目录 计数排序 完整代码: 桶排序 完整代码: 基数排序 完整代码: 完整测试类 总结 计数排序 简单解释:这个排序算法看名字也很好理解,就是就是额外找个数组来计数,然后在这个数组从小到大或从大到小把数取出来即可. 完整代码: package com.keafmd.Sequence; /** * Keafmd * * @ClassName: CountSort * @Description: 计数排序 * @author: 牛哄哄的柯南 * @date: 2021-06-24 11:31 */

  • JAVA十大排序算法之快速排序详解

    目录 快速排序 问题 思路 荷兰国旗问题 代码实现 时间复杂度 算法稳定性 总结 快速排序 快速排序是对冒泡排序的一种改进,也是采用分治法的一个典型的应用.JDK中Arrays的sort()方法,具体的排序细节就是使用快速排序实现的. 从数组中任意选取一个数据(比如数组的第一个数或最后一个数)作为关键数据,我们称为基准数(pivot,或中轴数),然后将所有比它小的数都放到它前面,所有比它大的数都放到它后面,这个过程称为一趟快速排序,也称为分区(partition)操作. 问题 若给定一个无序数组

  • JAVA十大排序算法之归并排序详解

    目录 归并排序 怎么分 怎么治 代码实现 时间复杂度 算法稳定性 总结 归并排序 归并,指合并,合在一起.归并排序(Merge Sort)是建立在归并操作上的一种排序算法.其主要思想是分而治之.什么是分而治之?分而治之就是将一个复杂的计算,按照设定的阈值进行分解成多个计算,然后将各个计算结果进行汇总.即"分"就是把一个大的通过递归拆成若干个小的,"治"就是将分后的结果在合在一起. 若将两个有序集合并成一个有序表,称为2-路归并,与之对应的还有多路归并. 怎么分 对于

  • JAVA十大排序算法之冒泡排序详解

    目录 冒泡排序 代码实现 代码实现 时间复杂度 算法稳定性 总结 冒泡排序 1.从数组头开始,比较相邻的元素.如果第一个比第二个大(小),就交换它们两个 2.对每一对相邻元素作同样的工作,从开始第一对到尾部的最后一对,这样在最后的元素应该会是最大(小)的数 3.重复步骤1~2,重复次数等于数组的长度,直到排序完成 代码实现 对下面数组实现排序:{24, 7, 43, 78, 62, 98, 82, 18, 54, 37, 73, 9} 代码实现 public class BubbleSort {

  • JAVA十大排序算法之选择排序详解

    目录 选择排序 代码实现 动图演示 代码实现 时间复杂度 算法稳定性 总结 选择排序 1.找到数组中最大(或最小)的元素 2.将它和数组的第一个元素交换位置(如果第一个元素就是最大(小)元素那么它就和自己交换) 3.在剩下的元素中找到最大(小)的元素,将它与数组的第二个元素交换位置.如此往复,直到将整个数组排序. 代码实现 对下面数组实现排序:{87, 23, 7, 43, 78, 62, 98, 81, 18, 53, 73, 9} 动图演示 代码实现 public class Selecti

  • JAVA十大排序算法之插入排序详解

    目录 插入排序 代码实现 动图演示 代码实现 时间复杂度 算法稳定性 总结 插入排序 当我们在玩扑克牌的时候,总是在牌堆里面抽取最顶部的一张然后按顺序在手中排列. 插入排序是指在待排序的元素中,假设前面n-1(其中n>=2)个数已经是排好顺序的,现将第n个数插到前面已经排好的序列中,然后找到合适自己的位置,使得插入第n个数的这个序列也是排好顺序的. 1.对于未排序数据(一般取数组的二个元素,把第一个元素当做有序数组),在已排序序列中从左往右扫描,找到相应位置并插入. 2.为了给要插入的元素腾出空

  •  Java数据结构的十大排序

    目录 1.直接插入排序 1.1 动图演示 1.2 插入排序的思路 1.3 代码实现 1.4 性能分析 2.希尔排序 2.1 原理 2.2 动图演示 2.3 代码实现 2.4 性能分析 3.直接选择排序 3.1 动图演示 3.2 代码实现 3.3 性能分析 4.堆排序 4.1 动图演示 4.2 代码实现 4.3 性能分析 5.冒泡排序 5.1 动图演示 5.2 代码实现 5.3 性能分析 6.快速排序 6.1 原理 6.2 动图演示 6.3 实现方法 6.3.1 Hoare法 6.3.2 挖坑法

  • java版十大排序经典算法:完整代码

    目录 十大排序算法对比 冒泡排序 完整代码: 测试代码: 运行结果: 快速排序 完整代码: 总结 十大排序算法对比 关于最后一列的稳定性,我稍微解释下,例如对序列:1 2 4 2 6 排序,序列中存在两个2,如果我们把这两个2标记上(让他俩不同),排序之后,前面的2还在前面,那么就称这种排序是稳定的,反之不稳定. 冒泡排序 简单解释: 原理就如算法名字一样,就像水中的气泡一样,每次我都把最大的或最小的放到最后面,这样总共需要n-1趟即可完成排序,这就是第一层循环,第二次循环就是遍历未被固定的那些

  • Python 数据结构之十大经典排序算法一文通关

    目录 1.冒泡排序 算法演示 算法步骤 算法实现 2.选择排序 算法演示 算法步骤 算法实现 3.简单插入排序 算法演示 算法步骤 算法实现 4.希尔排序 算法演示 算法步骤 算法实现 5.归并排序 算法演示 算法步骤 算法实现 6.快速排序 算法演示 算法步骤 算法实现 7.堆排序 算法演示 算法步骤 算法实现 8.计数排序 算法演示 算法步骤 算法实现 9.桶排序 算法演示 算法步骤 算法实现 10.基数排序 算法演示 算法步骤 算法实现 一文搞掂十大经典排序算法 今天整理一下十大经典排序算

  • Java 十大排序算法之冒泡排序刨析

    目录 冒泡排序原理 冒泡排序API设计 冒泡排序的代码实现 冒泡排序的时间复杂度分析 冒泡排序原理 ①比较相邻的元素,如果前一个元素比后一个元素大,则交换这两个元素的位置 ②对每一对相邻的元素循环上面的步骤,最终最后面的元素就是最大值 冒泡排序API设计 类名 Bubble 构造方法 Bubble:创建Bubble对象 成员方法 1.public static void sort(Comparable[] a):对数组内元素进行排序 2.private static void greater(C

  • Java 十大排序算法之选择排序刨析

    目录 选择排序原理 选择排序API设计 选择排序代码实现 选择排序的时间复杂度 选择排序原理 ①假设第一个索引处的元素为最小值,和其他值进行比较,如果当前的索引处的元素大于其他某个索引处的值,则假定其他某个索引处的值为最小值,最后找到最小值所在的索引 ②交换第一个索引处和最小值所在的索引处的值 选择排序API设计 类名 Selection 构造方法 Selection():创建Selection对象 成员方法 1.public static void sort(Comparable[] a):对

  • Java 十大排序算法之插入排序刨析

    目录 插入排序原理 插入排序API设计 插入排序代码实现 插入排序的时间复杂度分析 插入排序原理 ①把所有元素分成已排序和未排序两组 ②找到未排序组的第一个元素,向已经排序的组中进行插入 ③倒序遍历已经排好的元素,依次和待插入的元素进行比较,直到找到一个元素小于等于待插入元素,那么就把待插入元素放到这个位置,其他元素向后移动一位 插入排序API设计 类名 Insertion 构造方法 Insertion():创建Insertion对象 成员方法 1.public static void sort

  • Java 十大排序算法之归并排序刨析

    目录 归并排序原理 归并排序API设计 归并排序代码实现 归并排序的时间复杂度分析 归并排序原理 1.尽可能的一组数据拆分成两个元素相等的子组,并对每一个子组继续拆分,直到拆分后的每个子组的元素个数是1为止. ⒉将相邻的两个子组进行合并成一个有序的大组. 3.不断的重复步骤2,直到最终只有一个组为止. 归并排序API设计 类名 Merge 构造方法 Merge():创建Merge对象 成员方法 1.public static void sort(Comparable[] a):对数组内的元素进行

  • Java 十大排序算法之希尔排序刨析

    目录 希尔排序原理 希尔排序的API设计 希尔排序的代码实现 希尔排序是插入排序的一种,又称"缩小增量排序",是插入排序算法的一种更高效的改进版本. 希尔排序原理 1.选定一个增长量h,按照增长量h作为数据分组的依据,对数据进行分组. 2.对分好组的每一组数据完成插入排序. 3.减小增长量,最小减为1,重复第二步操作. 希尔排序的API设计 类名 Shell 构造方法 Shell():创建Shell对象 成员方法 1.public static void sort(Comparable

  • Java 十大排序算法之堆排序刨析

    二叉堆是完全二叉树或者是近似完全二叉树. 二叉堆满足二个特性︰ 1.父结点的键值总是大于或等于(小于或等于)任何一个子节点的键值. 2.每个结点的左子树和右子树都是一个二叉堆(都是最大堆或最小堆). 任意节点的值都大于其子节点的值--大顶堆(最后输出从小到大排) 任意节点的值都小于其子节点的值---小顶堆(最后输出从大到小排) 堆排序步骤 1.堆化,反向调整使得每个子树都是大顶或者小顶堆(建堆) 2.按序输出元素∶把堆顶和最末元素对调,然后调整堆顶元素(排序) 堆排序代码实现(大顶堆) publ

随机推荐