ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

【学习笔记】八大排序(待更新)

2022-07-16 09:00:10  阅读:145  来源: 互联网

标签:八大 temp int 笔记 public 有序 array 排序 比较


八大排序(待更新)

 

一、 冒泡排序

1.什么是冒泡排序?

冒泡排序的英文是Bubble Sort ,是一种最基础的交换排序,之所以叫冒泡排序,是因为每个元素都可以像小气泡一样,根据自身大小一点一点地向数组一侧移动。

原理:

每一趟只能确定将一个数归位,即第一趟只能确定将末尾上的数归位,第二趟只能将倒数第二位上的数归位,以此类推下去。如果有 n 个数进行排序,只需将 n-1 个数归位,也就是要进行n-1 趟操作。

而每一趟都需要从第一位开始进行相邻的两个数的比较,将较大的数放后面,比较完毕之后向后挪一位继续比较下面两个相邻的数大小关系,重复此步骤,直到最后一个还没归位的数。

2.动图展示

 

3.时间复杂度

比较4个数排完序需要3趟,第一趟需要比较三次,第二趟需要比较两次,第三趟需要比较一次,总共需要比较3+2+1 = 6次

如果有n个数,则需要比较 (n-1)+(n-2)+......2+1次,显然这是一个等差数列

 

根据复杂度的规则,去掉最低价项(n/2),且去掉常数系数,可以得到复杂度为O(n^2)

 

4.冒泡排序初始版

package com.wzt.array;

import java.util.Arrays;

public class ArrayDemo04 {
   public static void main(String[] args) {
       int[] a = {23,14,6,89,77,3};
       int[] result = bubbleSort(a);
       System.out.println(Arrays.toString(result));

  }
   public static int[] bubbleSort(int[] array){
       int temp = 0;
       for (int i = 0; i < array.length-1; i++) {   //外层循环控制的是趟数
           for (int j = 0; j < array.length-(i+1); j++) {    //里层循环控制的是每趟比较的次数 其中i+1是第几趟
               if (array[j] > array[j+1]){
                   temp = array[j];
                   array[j] = array[j+1];
                   array[j+1] = temp;
              }
          }
      }
       return array;
  }
}

存在的问题

如果在第二趟结束后数组已经有序,如下

[23,14,6,89,77] 第一趟-------> [14,6,23,77,89] 第二趟-------> [6,14,23,77,99]

那么按照以上代码,算法依旧会兢兢业业地执行第三趟、第四趟,造成了时间上的浪费

我们可以利用布尔量作为标记,如果在本轮排序中,元素有交换,则说明数列无序,如果没有元素交换,说明元素已经有序,直接跳出大循环

package com.wzt.array;

import java.util.Arrays;

public class ArrayDemo04 {
   public static void main(String[] args) {
       int[] a = {23,14,6,89,77,3};
       int[] result = bubbleSort(a);
       System.out.println(Arrays.toString(result));

  }
   public static int[] bubbleSort(int[] array){
       int temp = 0;
       for (int i = 0; i < array.length-1; i++) {   //外层循环控制的是趟数
           boolean flag = false;
           for (int j = 0; j < array.length-(i+1); j++) {    //里层循环控制的是每趟比较的次数 其中i+1是第几趟
               if (array[j] > array[j+1]){
                   flag = true;    //如果发生了元素交换,则令flag为true
                   temp = array[j];
                   array[j] = array[j+1];
                   array[j+1] = temp;
              }
          }
           //执行完一趟之后,判断是否有元素交换,有则说明数组无序,没有说明有序,直接跳出大循环
           if(!flag){
               break;
          }
      }
       return array;
  }
}

新问题

如果数组中前半部分是无序的,而后半部分是有序的,比如(3,4,2,1,5,6,7,8),这个数组后半部分许多元素已经有序,但每一趟依然往后比较了许多次

 

第一趟:

3和4比较,3小于4,不用交换

然后4与2 比较 ,4大于2,交换位置

然后4与1比较,交换位置

然后,后面是有序数组,但依旧需要两两比较

4与5比较,5与6比较,6与7比较,7与8比较

然后进入第二趟

 

第二趟:

3与2比较,交换位置

3与1比较,交换位置

然后发现,后面又是有序数组了

3与4比较,4与5比较,....... 白白比较了很多次

 

如何优化?

对于这个问题,关键在于数列有序区的界定,如果按照冒泡排序代码原始版分析的话,有序区的长度和排序的轮数是相等的,比如第一轮排序后,有序区长度是1,第二轮排序后有序区长度是2......

但是,实际数列有序区会大于这个数,也就是上面的例子,第二轮中,后面5个数都在有序区内,因此后面的比较就没有意义了。

我们可以这样做来避免这种情况,在每一轮排序的最后,记录一下最后一次元素交换的位置,那个位置是无序区数列的边界,在往后就是有序区了。

 

package com.wzt.array;

import java.util.Arrays;

public class ArrayDemo04 {
   public static void main(String[] args) {
       int[] a = {23,14,6,89,77,3};
       int[] result = bubbleSort(a);
       System.out.println(Arrays.toString(result));

  }
   public static int[] bubbleSort(int[] array){
       int temp = 0;
       //无序数列的边界,再往后就是有序区了
       int indexBorder = array.length-1;
       //记录每一次元素交换的位置
       int location = 0;

       for (int i = 0; i < array.length-1; i++) {   //外层循环控制的是趟数
           boolean flag = false;
           for (int j = 0; j < indexBorder; j++) {    //比较到哪个地方的位置
               if (array[j] > array[j+1]){
                   flag = true;    //如果发生了元素交换,则令flag为true
                   temp = array[j];
                   array[j] = array[j+1];
                   array[j+1] = temp;
                   location = j;    //记录最后一次元素交换的位置
              }
          }
           indexBorder = location;    //把元素交换的位置给无序数列的边界
           //执行完一趟之后,判断是否有元素交换,有则说明数组无序,没有说明有序,直接跳出大循环
           if(!flag){
               break;
          }
      }
       return array;
  }
}
 

标签:八大,temp,int,笔记,public,有序,array,排序,比较
来源: https://www.cnblogs.com/wztblogs/p/16483355.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有