zoukankan      html  css  js  c++  java
  • 冒泡排序

    冒泡排序(优化版)(交换排序):

      数组实现:

      顾名思义,冒泡排序,首先将一组乱序数字中的最大数移到最后,随后除去每次移动到最后的数字,再将前面的所有数字中最大数移到最后...以此类推。(也就是先排序后面的),这里做的优化就是基于后面已经排好序的情况下进行的,假如一组数:4、2、8、3、4、1,第一轮排好后:2、4、3、4、1、8,此时8已经排好,所以以后无需比较此数,设一个标志位记录本轮有没有进行交换动作,如若没有,说明已经排好序,不需要再进行后面的比较。

    冒泡排序是稳定的。(稳定是指:相同两个元素在排序前后的相对位置不发生改变)

      如果忘记了,可以先看下列分析图:

     具体代码:

     1 public static void bubbleSort(int[] nums) {
     2         int temp = 0;
     3         boolean flag = false;
     4         for (int j = 0; j < nums.length - 1; j++) {
     5             for (int i = 0; i < nums.length - 1 - j; i++) {// 此处-i是将后面的值确定化,并不再比较它们,减少内循环
     6 
     7                 if (nums[i] > nums[i + 1]) {//交换,并记录本轮是否有过交换
     8                     count++;//记录一共比较多少次
     9                     flag = true;
    10                     temp = nums[i];
    11                     nums[i] = nums[i + 1];
    12                     nums[i + 1] = temp;
    13                 }
    14             }
    15             if (!flag)// 优化: 说明本轮没有进行比较,避免第j次已经排好序的状态下,又继续排序.
    16                 return;17             else
    18                 flag = false;
    19         }
    20     }

      注意:测试时的计算机配置不同,结果可能不同,但是排序之间的相对结果应该是合理的。

      冒泡排序的最坏情况下:时间复杂度为O(n2)

      测试80000随机数,范围在1000w内的随机数。结果如下:

      前后差约为:16秒(效率很差,即使再怎么优化也不能提升,如果是很多数排序,千万不要用冒泡排序)

      before:2020/05/10 23:07:17:982
      after:2020/05/10 23:07:33:307

      比较了交换次数:1603714390

      链表实现:

     1     public void bubbleSort(Node head) {
     2         if (null == head.getNext()) {//验证链表是否为空
     3             throw new RuntimeException("head getnext is null");
     4         }
     5         boolean flag = false;//优化标志位
     6         for (int i = 0; i < size; i++) {
     7             Node temp = head;//代替辅助头结点
     8             while (temp.getNext() != head) {//由于采用循环双链表,所以判断当前结点下一个是否为头结点,如果是则一轮比较结束
     9                 Node n1 = temp;//保存当前结点
    10                 Node n2 = temp.getNext();//保存下一结点
    11                 if (n1.getValue() > n2.getValue()) {//开始比较进行交换
    12                     swap(n1, n2);//交换方法在下方
    13                     flag = true;
    14                     continue;//优化点(其实大数量下没什么卵用)
    15                 }
    16                 temp = temp.getNext();
    17             }
    18             if (!flag) {
    19                 return;
    20             } else {
    21                 flag = false;
    22             }
    23         }
    24     }
    25     //这里的交换方法,需要你仔细思量,最好在纸上画一下
    26     public void swap(Node node1, Node node2) {
    27         node1.getPre().setNext(node2);
    28         node2.setPre(node1.getPre());
    29         node1.setNext(node2.getNext());
    30         node2.getNext().setPre(node1);
    31         node1.setPre(node2);
    32         node2.setNext(node1);
    33     }

      测试:

      冒泡排序的优化在上万数量级下,没有什么卵用,冒泡退出舞台,没有可以挽留的余地了。链表形式的冒泡看看就行了。。。由于是环形双链表,其交换效率比移动数组还差!不要测试了,80000数据跑了几分钟。。。不如数组。

    
    
  • 相关阅读:
    程序员的学习和积累
    【STL】-迭代器的用法
    【STL】-list的用法
    【STL】-deque的用法
    【STL】- vector的用法
    数据结构-各种排序算法
    【STL】-priority_queue的用法
    数据结构-二项队列
    IT公司100题-8-智力题
    IT公司100题-7-判断两个链表是否相交
  • 原文地址:https://www.cnblogs.com/taichiman/p/12871128.html
Copyright © 2011-2022 走看看