当前位置: 首页 > news >正文

冒泡排序、插入排序、快速排序、堆排序、希尔排序、归并排序

目录

        • 冒泡排序
        • 插入排序
        • 快速排序(未优化版本)
        • 快速排序(优化版本)
        • 堆排序
        • 希尔排序
        • 归并排序
        • 各排序时间消耗对比

冒泡排序

冒泡排序核心逻辑就是对数组从第一个位置开始进行遍历,如果发现该元素比下一个元素大,则交换位置,如果不大,就拿着下一个比该元素大的元素向下继续比较,以此类推一直比较到最后,每一轮下来就会把当前最大的元素放到最后所以每一轮会确定一个最大元素。

    public void bubbleSort(int[] array) {for (int i = 0; i < array.length; i++) {int flag = 0;for (int j = 1; j < array.length-i; j++) {if (array[j - 1] > array[j]) {swap(array,j-1,j);flag = 1;}}if (flag == 0) {break;}}}

这里做了一个优化,当某一轮发现一个元素都没有移动的时候,就表示这个数组已经是有序的了,不理解的可以举一个已经有序的例子推敲一下,所以定义一个flag如果为0就表示一整伦下来都没有发生过移动直接跳出循环,排序完成。

时间复杂度:O(N^2)

稳定性:稳定

空间复杂度:O(1)

插入排序
    public void insertSort(int[] array) {for (int i = 1; i < array.length; i++) {int j = i - 1;int tmp = array[i];for (; j >= 0; j--) {if (array[j] >= tmp) {array[j+1] = array[j];} else {break;}}array[j+1] = tmp;}}

时间复杂度:O(N^2)

稳定性:稳定

空间复杂度:O(1)

快速排序(未优化版本)
	public void quickSort (int[] array) {quick(array,0,array.length-1);}private void quick(int[] array, int start, int end) {if (start >= end) {return;}// 一个是霍尔法一个是挖坑法,两个都可int part = partition1(array,start,end); // 霍尔法//int part = partition2(array,start,end); // 挖坑法quick(array,start,part-1);quick(array,part+1,end);}private int partition1(int[] array, int left, int right) {int tmp = array[left];int tmpIndex = left;while (left < right) {while (left < right && array[right] >= tmp) {right--;}while (left < right && array[left] <= tmp) {left++;}swap(array,left,right);}swap(array,tmpIndex,left);return left;}private int partition2(int[] array, int left ,int right) {int tmp = array[left];while (left < right) {while (left < right && array[right] >= tmp) {right--;}array[left] = array[right];while (left < right && array[left] <= tmp) {left++;}array[right] = array[left];}array[left] = tmp;return left;}

最好时间复杂度:O(N*logN)

最坏时间复杂度:O(N^2)

空间复杂度:O(logN)

稳定性:不稳定

快速排序(优化版本)
	public void quickSort (int[] array) {quick(array,0,array.length-1);}private void quick(int[] array, int start, int end) {if (start >= end) {return;}// 优化1(如果是少量的数据,直接插入排序速度是很快的,所以我们用直接插入排序处理数量小于等于15个的情况,不要小看这个优化,因为quickSort是树形的递归模式,在最后一层会有大量的数据存在,这个时候我们直接不进行递归直接进行插入排序可以节省大量的开销)if (end - start + 1 <= 15) {insertWithQuick(array,start,end);return;}// 优化2(三数取中优化,如果当一个数组比较趋于有序的情况下,那么构造出来的二叉树就是变成了一个链表,所以才会有时间复杂度区域O(N^2),我们只要打破这个顺序就好,我们直接去一个较为中间的值作为基准值就能均分了)int midIndex = findMidIndex(array,start,end);swap(array,start,midIndex);// 一个是霍尔法一个是挖坑法,两个都可int part = partition1(array,start,end); // 霍尔法//int part = partition2(array,start,end); // 挖坑法quick(array,start,part-1);quick(array,part+1,end);}private int partition1(int[] array, int left, int right) {int tmp = array[left];int tmpIndex = left;while (left < right) {while (left < right && array[right] >= tmp) {right--;}while (left < right && array[left] <= tmp) {left++;}swap(array,left,right);}swap(array,tmpIndex,left);return left;}private int partition2(int[] array, int left ,int right) {int tmp = array[left];while (left < right) {while (left < right && array[right] >= tmp) {right--;}array[left] = array[right];while (left < right && array[left] <= tmp) {left++;}array[right] = array[left];}array[left] = tmp;return left;}// 使用插入排序进行优化private void insertWithQuick(int[] array, int start, int end) {for (int i = start; i <= end; i++) {int j = i - 1;int tmp = array[i];for (; j >= start; j--) {if (array[j] >= tmp) {array[j+1] = array[j];} else {break;}}array[j+1] = tmp;}}// 使用三数取中找到中值下标private int findMidIndex(int[] array, int start, int end) {int midIndex = start + (end - start) / 2;if (array[start] > array[end]) {// end  startif (array[midIndex] < array[end]) {return end;} else if (array[midIndex] > array[start]) {return start;} else {return midIndex;}} else {// start  endif (array[midIndex] < array[start]) {return start;} else if (array[midIndex] > array[end]) {return end;} else {return midIndex;}}}

优化后的时间复杂度将会无限趋近于O(N*logN),空间复杂度不变

堆排序
    public void heapSort (int[] array) {createBigHeap(array);int end = array.length-1;while (end >= 0) {swap(array,0,end);end--;siftDown(array,0,end);}}private void createBigHeap(int[] array) {for (int parent = (array.length-2); parent >= 0; parent--) {siftDown(array,parent,array.length-1);}}private void siftDown(int[] array, int parent, int end) {int child = parent * 2 + 1;while (child <= end) {if (child + 1 <= end && array[child+1] > array[child]) {child++;}if (array[child] > array[parent]) {swap(array,child,parent);parent = child;child = child * 2 + 1;} else {break;}}}

时间复杂度:O(N*logN)

空间复杂度:O(logN)

稳定性:不稳定

希尔排序
    public void shallSort (int[] array) {int gap = array.length / 2;while (gap > 0) {shall(array,gap);gap /= 2;}}private void shall(int[] array, int gap) {for (int i = gap; i < array.length; i++) {int tmp = array[i];int j = i - gap;for (; j >= 0; j -= gap) {if (array[j] >= tmp) {array[j + gap] = array[j];} else {break;}}array[j+gap] = tmp;}}

希尔排序就是直接插入排序的升级版本

时间复杂度:不好计算业界公认的大概是O(N^1.3)

空间复杂度:O(1)

稳定性:不稳定

归并排序
    public void mergeSort(int[] array) {mergeFun(array,0,array.length-1);}private void mergeFun(int[] array, int start, int end) {if (start >= end) {return;}int midIndex = start + (end - start) / 2;mergeFun(array,start,midIndex);mergeFun(array,midIndex+1,end);// mergemerge(array, start, end, midIndex);}private void merge(int[] array, int start, int end, int midIndex) {int rs = midIndex + 1 , k = 0, tmpIndex = start;int[] tmpArray = new int[end - start +1];while (start <= midIndex && rs <= end) {if (array[start] < array[rs]) {tmpArray[k++] = array[start++];} else {tmpArray[k++] = array[rs++];}}while (start <= midIndex) {tmpArray[k++] = array[start++];}while (rs <= end) {tmpArray[k++] = array[rs++];}for (int j = tmpIndex; j <= end; j++) {array[j] = tmpArray[j - tmpIndex];}}

时间复杂度:O(N*logN)

空间复杂度:O(N)

稳定性:稳定

各排序时间消耗对比

为了更直观的观察每个排序有时间效率,我将这几个排序进行了一个对比,先随机生成要给数组大小为100000的随机数,随机数范围是0-10000,之后分别计算各个排序所消耗的时间单位是毫秒

public static void main(String[] args) {Sort sort = new Sort();// 原数组int[] array = createRandomNumber(100_000,10_000);// copy数组int[] array1 = Arrays.copyOf(array, array.length);long start1 = System.currentTimeMillis();sort.quickSort(array1);System.out.println("quickSort : " + (System.currentTimeMillis()-start1) );int[] array2 = Arrays.copyOf(array, array.length);long start2 = System.currentTimeMillis();sort.shallSort(array2);System.out.println("shallSort : " + (System.currentTimeMillis()-start2) );int[] array3 = Arrays.copyOf(array, array.length);long start3 = System.currentTimeMillis();sort.heapSort(array3);System.out.println("heapSort : " + (System.currentTimeMillis()-start3) );int[] array4 = Arrays.copyOf(array, array.length);long start4 = System.currentTimeMillis();sort.mergeSort(array4);System.out.println("mergeSort : " + (System.currentTimeMillis()-start4) );int[] array5 = Arrays.copyOf(array, array.length);long start5 = System.currentTimeMillis();sort.insertSort(array5);System.out.println("insertSort : " + (System.currentTimeMillis()-start5) );int[] array6 = Arrays.copyOf(array, array.length);long start6 = System.currentTimeMillis();sort.bubbleSort(array6);System.out.println("bubbleSort : " + (System.currentTimeMillis()-start6) );}private static int[] createRandomNumber (int size, int range) {int[] array = new int[size];for (int i = 0; i < size; i++) {array[i] = new Random().nextInt(range);}return array;}

在这里插入图片描述

所以大家还是少用冒泡吧,虽然简单但是效率感人~ 快排还是牛掰

相关文章:

  • RPA机器人技术原理初探
  • OpenCv高阶(三)——图像的直方图、图像直方图的均衡化
  • Token与axios拦截器
  • MATLAB脚本实现了一个三自由度的通用航空运载器(CAV-H)的轨迹仿真,主要用于模拟升力体在不同飞行阶段(初始滑翔段、滑翔段、下压段)的运动轨迹
  • 算法题(126):前缀和
  • 【Netty篇】EventLoopGroup 与 EventLoop 详解
  • SAP ECCS 标准报表 切换为EXCEL电子表格模式
  • 基于springboot+vue的数码产品抢购系统
  • 0701表单组件-react-仿低代码平台项目
  • Abstract (抽象类)和 Interface (接口)的区别
  • PowerBi中Drillthrough功能怎么使用?
  • 多功能门禁系统的设计
  • Vue+Threejs项目性能优化
  • Linux驱动开发进阶(十)- I2C子系统BSP驱动
  • 请详细说明下面训练阶段的差别: Supervised Fine-Tuning、Reward Modeling、PPO、DPO、KTO、Pre-Training
  • 【MySQL】索引特性
  • OpenCV 图形API(37)图像滤波-----分离过滤器函数sepFilter()
  • SvelteKit 最新中文文档教程(20)—— 最佳实践之性能
  • 系统架构设计师:系统架构概述案例分析与简答题、详细解析与评分要点
  • 【Caddy】:现代化、自动 HTTPS 的 Web 服务器新星
  • 优化 保证排名/广州seo公司官网
  • 会员网站开发/百度网站站长工具
  • 专业建设网站多少钱/seo网络营销技巧
  • 素颜网站建设/北大青鸟培训机构官网
  • 做网站时怎么更改区域内的图片/seo优化大公司排名
  • 社会信用体系建设双公示网站/广州网站建设工作室