编程语言
首页 > 编程语言> > 八种排序算法总结

八种排序算法总结

作者:互联网

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档

八种排序算法


前言

自学了几种常见的排序算法,做个简单的总结


一、排序算法(Sort Algorithm)的分类

在这里插入图片描述

二、八种排序

1.冒泡排序

代码如下(示例):

// 将前面额冒泡排序算法,封装成一个方法 ,从小到大排序
public static void bubbleSort(int[] arr) { 
		int temp;
        Boolean flag = false; //标识变量,表示是否进行过交换,
        //一趟下来,如果没有交换过,说明数组已经有序,则不需继续遍历
        for(int i = 0;i < arr.length;i++ ) {
            for(int j = 0; j < arr.length-1-i;j++){
                if (arr[j] > arr[j+1]) {//前一个比后一个大,则交换
                    flag = true;
                    temp = arr[j];
                    arr[j] = arr[j + 1];
                    arr[j+1] = temp;
                }
            }

			//一趟之后,进行判断,是否交换过
            if(!flag){
                break;
            } else {
            //交换过,要重新设置为false,为下一趟做准备
                flag = false;
            }
        }


}

2.选择排序

2.1思路分析

  1. 选择排序一共进行:数组大小-1轮
  2. 每一轮选出一个最小的数排在第一位

代码如下(示例):

 private static void Select(int[] arr){
        
        for(int i = 0;i<arr.length-1;i++){
            
            int minIndex = i;//记录最小值下标
            int min = arr[i];//记录最小值
            for(int j = i;j < arr.length-1;j++){
                if (arr[j] < min) {//找到一个数比当前数小,就记录下来
                    min = arr[j];
                    minIndex = j;
                }
            }

            if(minIndex != i){//找到一个最小的值,则和最前面的数进行交换
                arr[minIndex] = arr[i];
                arr[i] = min;
            }
        }

    }

3.插入排序(Insertion Sorting)

3.1 思路

插入排序的基本思想是:把 n 个待排序的元素看成为一个有序表和一个无序表,开始时有 序表中只包含一个元素,无序表中包含有 n-1 个元素,排序过程中每次从无序表中取出第一个元素,把它的排序码依次与有序表元素的排序码进行比较,将它插入到有序表中的适当位置,使之成为新的有序表。

3.2 代码

  public static void insert(int[] arr){
        int insertVal = 0;
        int insertIndex = 0;

        for(int i = 1;i < arr.length;i++){
            insertVal = arr[i];//记录插入的值
            insertIndex = i -1;//记录插入数的前一个数

            while(insertIndex >= 0 && (insertVal < arr[insertIndex])){
            //比较当前插入值和当前值,找出最小的位置插入
                arr[insertIndex+1] = arr[insertIndex];//将数后移,空出插入的位置
                insertIndex--;//往前面找
            }

            if(insertIndex+1 != i){//判断指针是否有动
                arr[insertIndex + 1] = insertVal;//如果有动,就将当前位置改为插入值
                //为什么insertIndex 要加1 : 因为前一步出来的时候insertIndex 是多减了一下
            }

        }
    }

4.希尔排序

4.1 基本思想

希尔排序 是把记录按下标的一定增量分组,对每组使用直接插入排序算法排序;随着增量逐渐减少,每组包含 的关键词越来越多,当增量减至 1 时,整个文件恰被分成一组,算法便终止

4.2 思路图

在这里插入图片描述

  int insertVal;//记录插入值
        int insertIndex;//记录当前要插入值对应的下标
        for(int gap = arr.length/2;gap > 0;gap /= 2){
            //将整个数据分组,分为length / 2组,并不断缩小增量 gap /= 2

            for(int i = gap;i < arr.length;i++){
                //每一次分组都用插入排序
                //记录每一次插入排序的初始位置,从后面开始
                insertVal = arr[i]; //插入值初始化
                insertIndex = i;    //当前要插入值的下标
                while(insertIndex - gap >= 0 && (insertVal < arr[insertIndex-gap]   )){
                    //当前要插入的前一个必须有值,否则就不会进入
                    //并且前一个值大于要插入的值,才能进入
                    arr[insertIndex] = arr[insertIndex-gap];//将前一个值移到当前位置
                    insertIndex-=gap;//然后位置向前移动一步
                }

                if(insertIndex != i){//如果当前值没有动,说明当前值是已经小的了,不用插入了
                    arr[insertIndex] = insertVal;//否则,就将插入值,插入到当前位置
                }
            }
        }

5. 快速排序(Quicksort)

5.1思路

在这里插入图片描述

5.2 代码

 public static void QuickSort(int[] arr, int left, int right){
        int l = left;
        int r = right;
        int pivot = arr[(left+right)/2];//记录中间值
        int temp = 0;//临时变量,用于交换

        while (l < r ){
            while(arr[l] < pivot){//在左边找到一个比pivot大的数的下标
                l++;
            }
            while(arr[r] > pivot){//在右边找到一个比pivot小的数的下标
                r--;
            }

            if (l >= r) {
                break;
            }

            //交换左右两个值
            temp = arr[l];
            arr[l] = arr[r];
            arr[r] = temp;

            if(arr[l] == pivot){
                r--;
            }
            if(arr[r] == pivot){
                l++;
            }
            if(l == r){
                l++;
                r--;
            }

            if(left < r){
                QuickSort(arr,left,r);
            }

            if(right > l){
                QuickSort(arr, l, right);
            }
        }
    }

6. 归并排序

6.1 思路

在这里插入图片描述

6.2 代码

  //分
   public static void mergeSort(int[] arr, int left, int right, int[] temp) {
        if(left < right){
           int mid = (left + right)/2;
           mergeSort(arr,left,mid,temp);
           mergeSort(arr,mid+1,right,temp);
            merge(arr,left,mid,right,temp);
        }
    }

	//治
    public static void merge(int[] arr, int left, int mid, int right, int[] temp) {
        int i = left;//左边有序序列的初始索引
        int j = mid + 1;//右边有序序列的初始索引
        int t = 0;//指向temp数组的当前索引

        while(i <= mid && j <= right){//继续
            //如果左边的有序序列的当前元素,小于
            if(arr[i] <= arr[j]){
                temp[t] = arr[i];
                t++;
                i++;
            } else {
                temp[t] = arr[j];
                t++;
                j++;
            }
        }

        while(i <= mid){
            temp[t++] = arr[i++];
        }

        while(j <= right){
            temp[t++] = arr[j++];
        }

        t = 0;
        int tempLeft = left;
        while(tempLeft <= right){
            arr[tempLeft++] = temp[t++];
        }
    }

7.基数排序

7.1 思路

将所有待比较数值统一为同样的数位长度,数位较短的数前面补零。然后,从最低位开始,依次进行一次排序。 这样从最低位排序一直到最高位排序完成以后, 数列就变成一个有序序列

7.2 代码

 public static void radixSort(int arr[]){
        //得到数组中最大的数的位数
        int max = arr[0];
        for (int i = 0; i < arr.length; i++) {
            if(arr[i] > max ){
                max = arr[i];
            }
        }

        //得到最大的数是多少位
        int maxLength = (max + "").length();

        //定义一个二维数组,表示 10 个桶, 每个桶就是一个一维数组
        // 说明
        // 1. 二维数组包含 10 个一维数组
        // 2. 为了防止在放入数的时候,数据溢出,则每个一维数组(桶),大小定为 arr.length
        // 3. 名明确,基数排序是使用空间换时间的经典算法

        int[][] bucket = new int[10][arr.length];

        //为了记录每个桶中,实际存放了多少个数据,我们定义一个一维数组来记录各个桶的每次放入的数据个数
        //比如:bucketElementCounts[0] , 记录的就是 bucket[0] 桶的放入数据个数
        int[] bucketElementCounts = new int[10];

        for(int i = 0,n = 1; i < maxLength;i++,n *= 10){
            //n是用于的到对应数的位数
            for (int j = 0; j < arr.length; j++) {
                int digitOfElement = arr[j]/n % 10;
                bucket[digitOfElement][bucketElementCounts[digitOfElement]] = arr[j];
                bucketElementCounts[digitOfElement]++;
            }

            //按照这个桶的顺序(一维数组的下标依次取出数据,放入原来数组)
            int index = 0;
            //遍历每一桶,并将桶中是数据,放入到原数组
            for (int k = 0; k < bucketElementCounts.length; k++) {
                if (bucketElementCounts[k] != 0){
                    for (int l = 0; l < bucketElementCounts[k]; l++) {
                        arr[index++]  = bucket[k][l];
                    }
                }

                //第 i+1 轮处理后,需要将每个 bucketElementCounts[k] = 0 !!!!
                bucketElementCounts[k] = 0;
            }
        }
    }

8.堆排序

跟基数排序原理差不多,这里就省略了


总结

常见算法的比较

在这里插入图片描述

总结
几种排序算法,大多数都是从尚硅谷学习,大家有兴趣可以去看视频学习,在b站就可以找到相视频

标签:arr,temp,int,insertIndex,八种,++,算法,排序
来源: https://blog.csdn.net/m0_52963553/article/details/120126440