首页 > 代码库 > 2.冒泡排序
2.冒泡排序
(1)冒泡排序(Bubble Sort):
它是排序算法的初级算法。在排序算法中,冒泡排序算法使用率较低,主要因为它适用于规模较小的排序,并且效率低下。
算法名字由来:越大的元素会慢慢交换浮到顶端,直到所有元素排序完毕。
主要思想:
(1)从后向前遍历当前剩余未排序元素,比较相邻元素,如果前者小于后者,二者交换。
(2)每次会找出一个最大元素,因此也就是说每次循环会固定住一个元素的最终位置。
(3)因此如果排序n个元素,需要外层n次循环即可完成数据的排序。
冒泡排序源代码如下:(每个人版本不同,建议大家理解思想后自行编写)
public void bubble_Sort(int[] arr){ for(int i=0;i<arr.length-1;i++){ for(int j=arr.length-1;j>i;j--){ if(arr[j-1]<arr[j]){ int temp=arr[j-1]; arr[j-1]=arr[j]; arr[j]=temp; } } } } public static void main(String[] args) { int[] arr={1,2,5,4,3}; new Bubble_Sort().bubble_Sort(arr); System.out.println(Arrays.toString(arr)); }
冒泡排序特点:(非改进版冒泡排序)
(1)冒泡排序是稳定排序算法:因为冒泡排序会对相邻元素进行比较,如果元素相等则不进行处理,也就是说,不会改变相等元素的相对位置。
(2)冒泡排序的最坏时间复杂度为O(n2).冒泡排序有两层循环,因此时间复杂度为O(n2).最好时间复杂度为O(n)(当元素有序的时候)。
(3)冒泡排序的平均空间复杂度为O(1)。最好空间复杂度为0(当元素有序的时候),最坏空间复杂度为O(n)(当元素逆序的时候)。
注意:有人会考虑将空间复杂度O(1)转换为0,通过两个元素交换方式,例如:
a=a+b; b=a-b; a=a-b;// a=a*b; b=a/b; a=a/b; // b=a^b; a=a^b; b=a^b;
这样处理很可能因此数据的溢出,因此建议不要使用,除非题目给出限定条件,并且要求空间复杂度时再行考虑使用。
(2)改进的冒泡排序:
1.如果当前剩余排序元素有序则退出循环,代码如下:
public void bubble_Sort_change1(int[] arr){ boolean flag=false; for(int i=0;i<arr.length-1&&!flag;i++){ flag=true; for(int j=arr.length-1;j>i;j--){ if(arr[j-1]<arr[j]){ flag=false; int temp=arr[j-1]; arr[j-1]=arr[j]; arr[j]=temp; } } } }
2.记录上一次扫描停止的位置,此时说明停止位置之前的元素均已完成排序,将其设置为下次循环的起始位置,免于从i开始。
代码如下:
public void bubble_Sort_change2(int[] arr){ int xLoc=0,yLoc=0; for(int i=0;i<arr.length-1;i++){ xLoc=yLoc; for(int j=arr.length-1;j>xLoc;j--){ if(arr[j-1]<arr[j]){ int temp=arr[j-1]; arr[j-1]=arr[j]; arr[j]=temp; yLoc=j; } } if(xLoc==yLoc) break; } }
3.双向扫描。处理大规模数据时效率有提高。桥后两个方向进行元素比较处理。
//双向扫描 public void bubble_Sort_change3(int[] arr){ int low=0,high=arr.length-1; int index=0; while(low<high){ for(int i=low;i<high;i++){ if(arr[i]<arr[i+1]){ int temp=arr[i];arr[i]=arr[i+1];arr[i+1]=temp; index=i; } } low=index; for(int i=high;i>low;i--){ if(arr[i-1]<arr[i]){ int temp=arr[i-1]; arr[i-1]=arr[i]; arr[i]=temp; index=i; } } high=index; } }
2.冒泡排序