数据结构与算法之排序算法(经典思路图解加实现)

本文深入讲解八大经典排序算法,包括冒泡排序、快速排序、插入排序、希尔排序、选择排序、归并排序等,通过代码实例和图解帮助理解算法原理及应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前言

在这里插入图片描述
一个算法中语句执行的次数成为语句频度,记为T(n)。
时间复杂度介绍
常见的时间复杂度
想了解上面时间复杂度情况可看[时间复杂度举例](https://blog.csdn.net/qq_17534301/article/details/82872357
稳定性:任意两个相等的数据,排序后相对位置不变。

八大排序算法

1.冒泡排序

①思想:冒泡排序是一种交换排序,它的基本思想是:两两比较相邻记录的关键字,如果反序则交换,直到没有反序的记录为止。图解如下
在这里插入图片描述
②代码实现

public class BubbleSort {
    public static void main(String[] args) {
        int[] a = { 4, 5, 1, 7, 0, 9, 6, 3, 2, 8 };
        bubbleSort(a);
    }
    public static void bubbleSort(int[] arr) {//传入数组
            for (int i = 1; i < arr.length; i++) {//控制共比较多少轮
            for (int j = 0; j <= arr.length -1 - i; j++) { //控制每一轮的次数
                if (arr[j] > arr[j + 1]) {
                    int temp;    //用临时变量交换
                    temp = arr[j];
                    arr[j] = arr[j + 1];
                    arr[j + 1] = temp;
                }
            }
        }
        System.out.println(Arrays.toString(arr));
    }
}
//优化后的代码
public class BubbleSort {
    public static void main(String[] args) {
        int[] a = { 3,9,-1,10,20 };
        bubbleSort(a);
    }
    public static void bubbleSort(int[] arr) {//传入数组
        boolean flag =false;
        for (int i = 0; i < arr.length-1; i++) {//控制共比较多少轮
            for (int j = 0; j < arr.length -1 - i; j++) { //控制每一轮的次数
                if (arr[j] > arr[j + 1]) {
                    flag=true;
                    int temp;    //用临时变量交换
                    temp = arr[j];
                    arr[j] = arr[j + 1];
                    arr[j + 1] = temp;
                }
            }
            System.out.println("第"+(i+1)+"趟交换");
            System.out.println(Arrays.toString(arr));
            if(!flag){//如果在一次循环中没有交换,break
                break;
            }else{           //如果进入程序进行交换,重置flag
                flag=false;
            }
        }
    }
}

在这里插入图片描述

2.快速排序

①思想:、先从数列中取出一个数作为基准数分区过程,将比这个数大的数全放到它的右边,小于或等于它的数全放到它的左边,再对左右区间重复第二步,直到各区间只有一个数。
②图解与代码实现
第一次以0为基准
在这里插入图片描述

import java.util.Arrays;
public class QuickSort {
    public static void main(String[] args) {
        int arr [] ={2,1,3,4,0,7,5,9,4,10,-1};
        quicksort(arr,0,arr.length-1);
        System.out.println(Arrays.toString(arr));
    }
    public static void quicksort(int arr[] ,int start ,int end){
        if(start<end){
            int  stand=arr[start];//将数组第一个数字当作基准数
            int left = start;//记录下需要排序的下标
            int right= end;
            while(left<right){//循坏比标准数大的数,比标准数小的数
                while(left<right&&stand<=arr[right]){ //右边数字比标准数大,下标移动
                    right--;
                }
                arr[left]=arr[right];
                while(left<right&&arr[left]<stand){
                    left++;
                }
                arr[right]=arr[left];
            }
            arr[left]=stand;
        quicksort(arr,start ,left);
        quicksort(arr,left+1 ,end);
        }
    }
}

3.插入排序

①思想:在要排序的一组数中,假设前面(n-1)[n>=2] 个数已经是排好顺序的,现在要把第n个数插到前面的有序数中,使得这n个数也是排好顺序的。如此反复循环,直到全部排好顺序
②代码实现:

public class InsertSort {
    public static void main(String[] args) {
        int[] arr = new int[]{5, 3, 2, 8, 5, 9, 1, 0};
        insertSort(arr);
        System.out.println(Arrays.toString(arr));
    }
    public static void insertSort(int arr[]) {
        for (int i = 1; i < arr.length ; i++) {  //遍历所有数字
            if (arr[i] < arr[i - 1]) {
            int temp= arr[i];//把当前遍历数字存储起来
                //遍历当前数字前面所有数字
                int j;
                for ( j = i-1; j>=0&& arr[j]>temp ; j--) {
                //把前一个数字赋值给后一个
                    arr[j+1]=arr[j];
                }
                //把临时变量(外层for循坏的当前元素)赋值给不满足条件的后一个元素
                arr[j+1]=temp;
            }
        }
    }
}

4.希尔排序

其工作原理是定义一个步长来表示排序过程中进行比较的元素之间有多远的间隔,每次将具有相同间隔的数分为一组,进行插入排序。希尔排序的实质就是分组的插入排序
https://blog.csdn.net/qq_37466121/article/details/85957138

5.选择排序

https://blog.csdn.net/weixin_42312342/article/details/89305495
①工作原理是:每一次从待排序的数据元素中选出最小(或最大)的一个元素,存放在序列的起始位置,然后,再从剩余未排序元素中继续寻找最小(大)元素,然后放到已排序序列的末尾。以此类推,直到全部待排序的数据元素排完。 选择排序是不稳定的排序方法。
每次我只要最小的
流程②代码实现

public class SelectSort {
    public static void main(String[] args) {
        int [] arr = new int[]{3,5,1,2,0,6,9,8,4};
       selectSort(arr);
        System.out.println(Arrays.toString(arr));
    }
    public  static void selectSort(int [] arr){
        for (int i = 0; i <arr.length ; i++) {
            int mixIndex=i;//把当前遍历的数字和后面所有数字进行比较并记录下最小的数字下标
            for (int j = i+1; j <arr.length; j++) {
                 if(arr[mixIndex]>arr[j]) {//如果后面记录的数字比记录的最小的还小
                     mixIndex=j;
                 }
            }//如果最小的数字和当前遍历数的下标不一致,说明下标minindex的数比当前遍历的数更小
            if(i!=mixIndex){
                int temp =arr[i];
                arr[i]=arr[mixIndex];
                arr[mixIndex]=temp;
            }
        }
    }
}

6.归并排序

①Step1:先依次划分下去,如图中例子分三次
https://blog.csdn.net/k_koris/article/details/80508543
在这里插入图片描述
分到一定细度的时候,每一个部分就只有一个元素了,那么我们此时不用排序,对他们进行一次简单的归并就好了。
Step2,从下(小的组)到上进行回归归并
在这里插入图片描述
在这里插入图片描述
②代码实现

public class MergeSort {
    public static void main(String[] args) {
    int [] arr =new int[]{1,2,1,4,3,9};
    mergeSort(arr,0,arr.length-1);
        System.out.println(Arrays.toString(arr));
    }
    public static void mergeSort(int []arr, int low,int high){
        if(low<high){int middle =(low+high)/2;
        mergeSort(arr,low,middle);//处理左边
        mergeSort(arr,middle+1,high);//处理右边
       //归并
        merge(arr,low,middle,high);
        }
    }
    public static void merge(int [] arr,int low ,int middle, int high){
        //用于存储归并后的数组
        int  [] temp=new int[high-low+1];
        int i =low;//记录第一个数组中需要遍历的下标
        int j =middle+1;//记录第二个数组中需要遍历的下标
        int index =0;//记录在临时数组中存放的下标
        //遍历两个数组中小的数,放入临时数组中
        while (i<=middle&&j<=high){
            if (arr[i] <= arr[j]) {//第一个数组中的数字更小,将小的存放在临时数组
                temp[index]=arr[i];
                i++;
            }else{                 //第一个数组中的数字更小,将小的存放在临时数组
             temp[index]=arr[j];
             j++;
            }
            index++;
        }
        //因为如果当某一边数组没有数字,就无法进入while循坏,所以将另一边剩的数据也要存入,如123  4536
        while (j<=high){
            temp[index]=arr[j];
            j++;
            index++;
        }
        while (i<=middle){
            temp[index]=arr[i];
            i++;
            index++;
        }
        for (int k = 0; k <temp.length ; k++) {
            arr[k+low]=temp[k];
        }
    }
}

未完待续(贴上图片来源博客)

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值