排序算法原理及其实现

1. 冒泡排序(Bubble Sort)

  • 原理

    它重复地走访要排序的数列,一次比较两个元素,如果它们的顺序错误就把它们交换过来。走访数列的工作是重复地进行直到没有再需要交换,也就是说该数列已经排序完成。这个算法的名字由来是因为越小的元素会经由交换慢慢 "浮" 到数列的顶端。

  • Java 代码示例

java

public class BubbleSort {
    public static void bubbleSort(int[] arr) {
        int n = arr.length;
        for (int i = 0; i < n - 1; i++) {
            for (int j = 0; j < n - i - 1; j++) {
                if (arr[j] > arr[j + 1]) {
                    // 交换元素
                    int temp = arr[j];
                    arr[j] = arr[j + 1];
                    arr[j + 1] = temp;
                }
            }
        }
    }

    public static void main(String[] args) {
        int[] arr = {64, 34, 25, 12, 22, 11, 90};
        bubbleSort(arr);
        for (int num : arr) {
            System.out.print(num + " ");
        }
    }
}

2. 选择排序(Selection Sort)

  • 原理

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

  • Java 代码示例

java

public class SelectionSort {
    public static void selectionSort(int[] arr) {
        int n = arr.length;
        for (int i = 0; i < n - 1; i++) {
            int minIndex = i;
            for (int j = i + 1; j < n; j++) {
                if (arr[j] < arr[minIndex]) {
                    minIndex = j;
                }
            }
            // 交换找到的最小元素和当前位置元素
            if (minIndex!= i) {
                int temp = arr[i];
                arr[i] = arr[minIndex];
                arr[minIndex] = temp;
            }
        }
    }

    public static void main(String[] args) {
        int[] arr = {64, 34, 25, 12, 22, 11, 90};
        selectionSort(arr);
        for (int num : arr) {
            System.out.print(num + " ");
        }
    }
}

3. 插入排序(Insertion Sort)

  • 原理

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

  • Java 代码示例

java

public class InsertionSort {
    public static void insertionSort(int[] arr) {
        int n = arr.length;
        for (int i = 1; i < n; i++) {
            int key = arr[i];
            int j = i - 1;
            while (j >= 0 && arr[j] > key) {
                arr[j + 1] = arr[j];
                j--;
            }
            arr[j + 1] = key;
        }
    }

    public static void main(String[] args) {
        int[] arr = {64, 34, 25, 12, 22, 11, 90};
        insertionSort(arr);
        for (int num : arr) {
            System.out.print(num + " ");
        }
    }
}

4. 快速排序(Quick Sort)

  • 原理

    通过一趟排序将待排记录分割成独立的两部分,其中一部分记录的关键字均比另一部分的关键字小,则可分别对这两部分记录继续进行排序,以达到整个序列有序。通常选取第一个元素作为基准元素,然后从数列的两端开始向中间扫描,把比基准小的元素放到基准左边,比基准大的元素放到基准右边,经过这一趟排序后,基准元素就处在它最终排序后的正确位置上了,然后再递归地对左右两部分进行同样的操作。

  • Java 代码示例

java

public class QuickSort {
    public static void quickSort(int[] arr, int low, int high) {
        if (low < high) {
            int pivotIndex = partition(arr, low, high);
            quickSort(arr, low, pivotIndex - 1);
            quickSort(arr, pivotIndex + 1, high);
        }
    }

    private static int partition(int[] arr, int low, int high) {
        int pivot = arr[low];
        while (low < high) {
            while (low < high && arr[high] >= pivot) {
                high--;
            }
            arr[low] = arr[high];
            while (low < high && arr[low] <= pivot) {
                low++;
            }
            arr[high] = arr[low];
        }
        arr[low] = pivot;
        return low;
    }

    public static void main(String[] args) {
        int[] arr = {64, 34, 25, 12, 22, 11, 90};
        quickSort(arr, 0, arr.length - 1);
        for (int num : arr) {
            System.out.print(num + " ");
        }
    }
}

5. 归并排序(Merge Sort)

  • 原理

    采用分治法(Divide and Conquer)的一个非常典型的应用。将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。把长度为 n 的输入序列分成两个长度为 n/2 的子序列;对这两个子序列分别采用归并排序;将两个排序好的子序列合并成一个最终的排序序列。

  • Java 代码示例

java

public class MergeSort {
    public static void mergeSort(int[] arr) {
        if (arr.length < 2) {
            return;
        }
        int mid = arr.length / 2;
        int[] left = new int[mid];
        int[] right = new int[arr.length - mid];
        System.arraycopy(arr, 0, left, 0, mid);
        System.arraycopy(arr, mid, right, 0, arr.length - mid);

        mergeSort(left);
        mergeSort(right);

        merge(arr, left, right);
    }

    private static void merge(int[] arr, int[] left, int[] right) {
        int i = 0, j = 0, k = 0;
        while (i < left.length && j < right.length) {
            if (left[i] <= right[j]) {
                arr[k++] = left[i++];
            } else {
                arr[k++] = right[j++];
            }
        }
        while (i < left.length) {
            arr[k++] = left[i++];
        }
        while (j < right.length) {
            arr[k++] = right[j++];
        }
    }

    public static void main(String[] args) {
        int[] arr = {64, 34, 25, 12, 22, 11, 90};
        mergeSort(arr);
        for (int num : arr) {
            System.out.print(num + " ");
        }
    }
}

6. 堆排序(Heap Sort)

  • 原理

    利用堆这种数据结构所设计的一种排序算法。堆是一个近似完全二叉树的结构,并同时满足堆属性:即子节点的键值或索引总是小于(或者大于)它的父节点。首先将待排序序列构建成一个堆(一般是大顶堆或小顶堆,大顶堆用于升序排序,小顶堆用于降序排序),然后将堆顶元素与末尾元素交换,再对剩下的元素重新调整为堆,重复此过程,直到整个序列有序。

  • Java 代码示例

java

public class HeapSort {
    public static void heapSort(int[] arr) {
        int n = arr.length;
        // 构建大顶堆
        for (int i = n / 2 - 1; i >= 0; i--) {
            heapify(arr, n, i);
        }
        // 逐个取出堆顶元素并调整堆
        for (int i = n - 1; i > 0; i--) {
            int temp = arr[0];
            arr[0] = arr[i];
            arr[i] = temp;
            heapify(arr, i, 0);
        }
    }

    private static void heapify(int[] arr, int n, int i) {
        int largest = i;
        int left = 2 * i + 1;
        int right = 2 * i + 2;
        if (left < n && arr[left] > arr[largest]) {
            largest = left;
        }
        if (right < n && arr[right] > arr[largest]) {
            largest = right;
        }
        if (largest!= i) {
            int swap = arr[i];
            arr[i] = arr[largest];
            arr[largest] = swap;
            heapify(arr, n, largest);
        }
    }

    public static void main(String[] args) {
        int[] arr = {64, 34, 25, 12, 22, 11, 90};
        heapSort(arr);
        for (int num : arr) {
            System.out.print(num + " ");
        }
    }
}
相关推荐
A XMan.22 分钟前
JSON结构快捷转XML结构API集成指南
xml·java·前端·json·php
小林爱28 分钟前
【Compose multiplatform教程06】用IDEA编译Compose Multiplatform常见问题
android·java·前端·kotlin·intellij-idea·compose·多平台
HappyAcmen2 小时前
机器算法之逻辑回归(Logistic Regression)详解
算法·机器学习·逻辑回归
炸鸡配泡面3 小时前
Qt 12.28 day3
java·开发语言
get_money_3 小时前
代码随想录Day37 动态规划:完全背包理论基础,518.零钱兑换II,本周小结动态规划,377. 组合总和 Ⅳ,70. 爬楼梯(进阶版)。
java·笔记·算法·动态规划
get_money_3 小时前
代码随想录38 322. 零钱兑换,279.完全平方数,本周小结动态规划,139.单词拆分,动态规划:关于多重背包,你该了解这些!背包问题总结篇。
java·开发语言·笔记·算法·动态规划
jackiendsc5 小时前
雪花算法(Snowflake algorithm)介绍、优缺点及代码示例
算法·html·dreamweaver
憶巷5 小时前
设计模式的分类及作用
java·设计模式
向宇it6 小时前
【从零开始入门unity游戏开发之——C#篇36】C#的out协变和in逆变如何解决泛型委托的类型转换问题
java·开发语言·unity·c#·游戏引擎
天空之外1366 小时前
Spring Boot Actuator、Spring Boot Actuator使用、Spring Boot Actuator 监控、Spring程序监控
java·spring boot·spring