八大内部排序算法-冒泡\选择\插入\希尔排序

目录

一、冒泡排序算法

二、选择排序算法

三、插入排序算法

四、希尔排序算法


一、冒泡排序算法

  冒泡排序(Bubble Sorting)思想:

       通过对待排序序列从前向后(从下标较小的元素开始),依次比较相邻元素的值,若发现逆序则交换,使值较大的元素逐渐从前移向后部,就像水底下的气泡一样逐渐向上冒。

       以数组[3,9,-1,10,-2]为例 ,每趟排序结束完,数组后面多出一个最大数,后一趟比前一趟就少了一个比较的数,即每一趟排序的次数在逐渐减少。

优化:如果我们发现在某趟排序中,没有发生一次交换,可以提前结束冒泡排序。 

public static void bubbleSort(int[] arr) {
        System.out.println("原始数组~"+Arrays.toString(arr));
        int temp = 0;//临时变量做交换用
        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;
                    temp = arr[j];
                    arr[j] = arr[j + 1];
                    arr[j + 1] = temp;
                }
            }
            if (!flag) { //如果在这趟排序中,一次交换都没有发生过
                break;
            } else {
                flag = false;//超级重要,重置flag,进行下次判断
            }
            System.out.println("第" + (i + 1) + "趟排序~"+Arrays.toString(arr));
        }
}

二、选择排序算法

  选择排序(SelectSorting)思想:

  1. 遍历整个序列,将最小的数放在最前面。 假定当前数是最小数,然后和后面每个数进行比较,如果发现有比当前数更小的数,就重新确定最小数,并得到下标。当遍历到数组的最后,就得到本轮最小数和下标,交换。
  2. 遍历剩下的序列,将最小的数放在最前面。
  3. 重复第二步,直到只剩下一个数。

选择排序

public class SelectSort {

    public static void main(String[] args) {
        int[] arr = {32, 43, 23, 13, 5};
        selectSort(arr);
    }
    public static void selectSort(int[] arr){
        System.out.println("原始数组~"+Arrays.toString(arr));
        for (int i = 0; i < arr.length - 1; i++) {
            int min = arr[i];//假设的最小值索引
            int minIndex = i;//假设的最小值
            for (int j = i + 1; j < arr.length; j++) {
                if (min > arr[j]) {
                    min = arr[j];//更新最小值
                    minIndex = j;//更新最小值索引
                }
            }
            if (minIndex != i) {//如果发生过更新,代表要进行交换
                arr[minIndex] = arr[i];//前面的假定最小值的地位替换掉后面的真实最小值的地位
                arr[i] = min;//真实最小值替换掉前面的假定最小值
            }
            System.out.println("第" + (i + 1) + "趟排序~"+Arrays.toString(arr));
        }
    }
}

三、插入排序算法

  插入排序(InsertionSorting)思想:

  1.   将第一个数和第二个数排序,然后构成一个有序序列。
  2.   将第三个数插入这个有序序列,构成一个新的有序序列(和打麻将插牌一样)。
  3.   对第四个数、第五个数......直到最后一个数,重复第二步。

(1)从第2个数开始作为待插入的数,将有序序列从后往前遍历。

(2)当前一个数一直比待插入的数大,则将前一个数后移,继续往前。

(3)回到循环遍历条件,继续比较前一个数和待插入数的大小。遍历条件不满足循环结束,找到待插入的位置,将待插入的数插入。

public static void insertionSort(int[] arr) {
        System.out.println("原始数组~" + Arrays.toString(arr));
        for (int i = 1; i < arr.length; i++) {
            int target = arr[i];//从第2个数开始作为待插入的数
            int j = i;//j从i值开始记录
            //将有序序列从后往前遍历
            // 1.当前一个数一直比待插入的数大,则将前一个数后移,继续往前
            // 2.继续比较前一个数和待插入的数的大小
            while (j > 0 && arr[j - 1] > target) {
                arr[j] = arr[j - 1];//将前一个数后移
                j--;//继续往前
            }
            //找到待插入的位置,将待插入的数插入
            arr[j] = target;
            System.out.println("第" + i + "趟排序~" + Arrays.toString(arr));
        }
}

缺点: 当需要插入的数是较小的数时,后移的次数明显增多,对效率有影响.

四、希尔排序算法

希尔排序(Shell Sorting)思想:

       1959年Shell发明,第一个突破O(n2)的排序算法,希尔排序也是一种插入排序,它是简单插入排序经过改进之后的一个更高效的版本,它与插入排序的不同之处在于,它会优先比较距离较远的元素。希尔排序又叫缩小增量排序

        希尔排序是把记录按下标的一定增量分组,对每组使用直接插入排序算法排序;随着增量逐渐减少,每组包含的关键词越来越多,仅增量因子为1 时,整个序列作为一个表来处理,算法便终止。

        比较在希尔排序中是最主要的操作,而不是交换。用这样步长序列的希尔排序比插入排序和堆排序都要快,甚至在小数组中比快速排序还快,但是在涉及大量数据时希尔排序还是比快速排序慢。

public class SortTest {

    public static void main(String[] args) {
        int[] arr = {2, 3, 4, 5, 6, 7, 1, 8, 9,0};
        shellSort(arr, arr.length / 2);
        System.out.println(Arrays.toString(arr));
        //缩小增量
        shellSort(arr, arr.length / 2 / 2);
        System.out.println(Arrays.toString(arr));
        //缩小增量
        shellSort(arr, arr.length / 2 / 2 / 2);
        System.out.println(Arrays.toString(arr));
    }

    public static void shellSort(int[] arr, int gap) {
        //外层循环遍历每一个组,每个组在内层循环进行插入排序
        for (int k = 0; k < gap; k++) {
            //插入排序
            for (int i = k + gap; i < arr.length; i += gap) {
                int target = arr[i];
                int j = i;
                while (j > gap- 1 && arr[j - gap] > target) {
                    arr[j] = arr[j - gap];
                    j -= gap;
                }
                arr[j] = target;
            }
        }
    }
}

 

进行改进,把缩小增量的过程,加入到排序方法体内部。

public class SortTest {

    public static void main(String[] args) {
        int[] arr = {2, 3, 4, 5, 6, 7, 1, 8, 9,0};
        shellSort(arr);
    }

    public static void shellSort(int[] arr) {
        // 增量 gap, 并逐步的缩小增量
        for (int gap = arr.length / 2; gap > 0; gap /= 2) {
            for (int k = 0; k < gap; k++) {
                //直接插入排序
                for (int i = k + gap; i < arr.length; i += gap) {
                    int target = arr[i];
                    int j = i;
                    while (j > gap - 1 && arr[j - gap] > target) {
                        arr[j] = arr[j - gap];
                        j -= gap;
                    }
                    arr[j] = target;
                }
            }
            System.out.println("增量:"+gap+"-->"+Arrays.toString(arr));
        }
    }
}

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值