ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

【排序算法总结】

2026/9/20 23:54:19 拓冰建站 浏览量
【排序算法总结】

目录

  • 1. 稳点与非稳定排序
  • 2. 冒泡排序
  • 3. 简单选择排序
  • 4. 直接插入排序
  • 5. 快排
  • 6. 堆排
  • 7. 归并

在这里插入图片描述

1. 稳点与非稳定排序

  • 不稳定的:快排、堆排、选择
  • 原地排序:快排也是
  • 非原地排序:归并 和三个线性时间排序:桶排序 ,计数,基数

2. 冒泡排序

  • 时间复杂度 O(n*n)
  • 空间复杂度 O(1)
  • 稳定
public class ReviewToo {//1.冒泡排序 时间复杂度 O(n*n)  空间复杂度 O(1) 稳定public int[] BubbleSort(int[] a) {int temp;//空间复杂度的体现boolean flag;o:for (int i = 1; i < a.length; i++) {flag = false;for (int j = 0; j < a.length - i; j++) {if (a[j] > a[j + 1]) {temp = a[j];a[j] = a[j + 1];a[j + 1] = temp;flag = true;}}if (flag == false) {break o;}}return a;}

3. 简单选择排序

  • 时间复杂度 O(n*n)
  • 空间复杂度 O(1)
  • 不稳定
    //2.简单选择排序 时间复杂度 O(n*n)  空间复杂度 O(1) 不稳定public int[] simpleSelectSort(int[] a) {int temp, min;//空间复杂度的体现for (int i = 0; i < a.length - 1; i++) {min = i;for (int j = i + 1; j < a.length; j++) {if (a[min] > a[j]) {min = j;}}if (min != i) {temp = a[i];a[i] = a[min];a[min] = temp;}}return a;}

4. 直接插入排序

  • 时间复杂度 O(n*n)
  • 空间复杂度 O(1)
  • 稳定
    //3.直接插入排序 时间复杂度 O(n*n)  空间复杂度 O(1)  稳定public int[] straightInsertionSort(int[] a) {//第一个元素是有序表 后面的是无序表 从后往前插for (int i = 1; i < a.length; i++) {int value = a[i];//要插入的元素int index = i - 1;//要插入的位置while (index >= 0 && value < a[index]) {if (value < a[index]) {a[index+1]=a[index];//索引前移继续找插入位置index--;}}//循环结束找到了插入位置a[index+1]=value;}return a;}}

5. 快排

  • 时间复杂度 O(n* log n)
  • 空间复杂度 O(log n)
  • 不稳定
//4.快排;
// 时间复杂度 O(n* log n)  空间复杂度 O(log n)  不稳定
public class FastSort {public static void quikSort(int[] arr, int left, int right) {// 1.快排终止条件(递归出口):只有一个元素或者无元素,不进行快排if (left >= right) {return;}// 2.选取基准元素:我们以数组左边的元素为基准元素int num = arr[left];// 定义首尾指针int start = left;int end = right;// 3.指针移动条件:指针未相交while (start < end) {// 先移动右边的指针(因为选取的是最左边的元素作为基准元素)//每次找出第一个比基准元素小的 end停到那while (start < end && arr[end] >= num) {end--;}// 再移动左边的指针while (start < end && arr[start] <= num) {start++;}// 两指针终止但没相交,交换元素if (start < end) {int temp = arr[start];arr[start] = arr[end];arr[end] = temp;}}// 4.循环结束两指针相交,排序结束,将基准元素放入指针相交位置arr[left] = arr[start];arr[start] = num;// 5.继续递归:分别对基准元素左右两边的元素进行快排 此时基准元素的左边全部小于它本身,右边全部大于它本身//快排左边quikSort(arr, left, start - 1);//快排右边quikSort(arr, start + 1, right);}//主函数public static void main(String[] args) {int[] arr = {34, 1, 5, -2, 0, 35, 36, 38};//初始的left=0;//right=arr.length-1;quikSort(arr, 0, arr.length - 1);for (int value : arr) {System.out.print(value+" ");}}
}

6. 堆排

//5.堆排;
public class Re {public static void heapSort(int[] arr) {int len = arr.length;int[] top = new int[100];for (int i = 0; i < top.length; i++) {top[i] = arr[i];}buildHeap(top);for (int i = len-1; i >=0 ; i--) {swap(arr,0,i);len--;heapify(arr,0,len);}}public static void buildHeap(int[] arr) {int len = arr.length;for (int i = len / 2 - 1; i >= 0; i--) {heapify(arr, i, len);}}public static void heapify(int[] arr, int i, int len) {int left = 2 * i + 1;int right = 2 * i + 2;int min = i;if (left < len && arr[min] > arr[left]) {min = left;}if (right < len && arr[min] > arr[right]) {min = right;}if (min != i) {swap(arr, min, i);heapify(arr, min, len);}}public static void swap(int[] arr, int i, int j) {int temp;temp = arr[i];arr[i] = arr[j];arr[j] = temp;}
}

7. 归并

//6.归并排序;
import java.util.Arrays;
public class MergeSort {//一、拆分部分public static void split(int[] arr,int left,int right,int[] temp){//递归拆分if (left<right){int mid=(left+right)/2;//左递归分解split(arr, left, mid, temp);//右递归分解split(arr, mid+1, right, temp);//合并merge(arr,left,right,mid,temp); //这么理解就像递归就是重复干一件事 你调用执行就可//上面 先左递归合并 再右递归合并}}//二、合并部分/*** @param arr   要进行排序的初始数组* @param left  左序列数组的初始索引* @param right 右序列数组的初始索引* @param mid   左序列和右序列的交接地方 中间索引*/public static void merge(int[] arr, int left, int right, int mid, int[] temp) {int i = left;//初始化i,作为左序列的初始索引int j = mid + 1;//初始化j,作为右序列的初始索引 mid是向下取整得来的int index = 0;//temp数组的当前索引//1.左右两边序列按照规则填充到temp数组 直到有一边处理完毕//循环条件 两边的数据均为处理完while (i <= mid && j <= right) {if (arr[i] <= arr[j]) { //左元素<=右 就把左里面的首位填充到temptemp[index] = arr[i];i++;//i后移index++;//index后移} else {//反之就填充右里面的首位temp[index] = arr[j];j++;index++;}}//当while循环结束 就有其中一边先处理完毕//2.把另一边中剩下的的数据直接依次填充到temp数组//满足哪个就去哪个循环进行填充while (j <= right) {temp[index] = arr[j];index++;j++;}while ((i <= mid)) {temp[index] = arr[i];index++;i++;}//3.temp数组拷贝到arr中//只有最后一次拷贝是把整个temp拷贝到arr数组中 前几次都是拷贝temp中的一部分//因为前几次的合并没有占满temp数组index=0;//temp索引归0;int tempLeft=left;
//        System.out.println("tempLeft="+tempLeft+" "+"right="+right);//第1次合并 tempLeft=0,right=1;//第2次合并 tempLeft=2,right=3;//第3次合并 tempLeft=0,right=3;//第4次合并 tempLeft=4,right=5;//第5次合并 tempLeft=6,right=7;//第6次合并 tempLeft=4,right=7;//第7次合并 tempLeft=0,right=7;//最后一次合并while (tempLeft<=right){arr[tempLeft]=temp[index];tempLeft++;index++;}}public static void main(String[] args) {int[] arr = new int[]{8, 4, 5, 7, 6, 2, 3, 9};int[] temp=new int[arr.length];split(arr,0, arr.length-1,temp);System.out.println(Arrays.toString(arr));}
}