交换类排序主要是通过两两比较待排元素的关键字,若发现与排序要求相逆,则“交换”
之。冒泡排序是交换类排序的一种。本篇文章讲解以下内容:
基本处理思想是通过对相邻两个数据的比较及其交换来达到排序的目的。
首先,将 n 个元素中的第一个和第二个进行比较,如果两个元素的位置为逆序,则交换两个元素的位置;进而比较第二个和第三个元素关键字,如此类推,直到比较第 n-1 个元素和第 n 个元素为止;
上述过程描述了起泡排序的第一趟排序过程,在第一趟排序过程中,我们将关键字最大的元素通过交换操作放到了具有 n 个元素的序列的最一个位置上。
然后进行第二趟排序,在第二趟排序过程中对元素序列的前 n-1 个元素进行相同操作,其结果是将关键字次大的元素通过交换放到第 n-1 个位置上。一般来说,第 i 趟排序是对元素序列的前 n-i+1 个元素进行排序,使得前 n-i+1 个元素中关键字最大的元素被放置到第 n-i+1 个位置上。排序共进行 n-1 趟,即可使得元素序列按关键字有序。
package com.algorithm.sorting;
/**
* 冒泡排序
* @author Administrator
*
*/
public class BubbleSort {
public static void BubbleSort(int[] arr) {
System.out.print("要排序的数组:");
for (int a = 0; a < arr.length; a++) {
System.out.print(arr[a] + "\t");
}
System.out.println("");
int temp;// 临时变量
for (int i = 0; i < arr.length - 1; i++) { // 表示排序次数,一共arr.length-1次。
for (int j = arr.length - 1; j > i; j--) {
if (arr[j] < arr[j - 1]) {//"<",代表正序即从小到大;">"代表逆序即从大到小
temp = arr[j];
arr[j] = arr[j - 1];
arr[j - 1] = temp;
}
}
System.out.print("第" + (i + 1) + "次排序结果:");
for (int a = 0; a < arr.length; a++) {
System.out.print(arr[a] + "\t");
}
System.out.println("");
}
System.out.print("最终排序结果:");
for (int a = 0; a < arr.length; a++) {
System.out.print(arr[a] + "\t");
}
}
public static void main(String[] args) {
int array[]={100, 20, 30,-1,99,53};
BubbleSort(array);
}
}
首先看正序的整个过程:
要排序的数组:100 20 30 -1 99 53
第1次排序结果:-1 100 20 30 53 99
第2次排序结果:-1 20 100 30 53 99
第3次排序结果:-1 20 30 100 53 99
第4次排序结果:-1 20 30 53 100 99
第5次排序结果:-1 20 30 53 99 100
最终排序结果:-1 20 30 53 99 100
再看逆序的整个过程:
要排序的数组:100 20 30 -1 99 53
第1次排序结果:100 99 20 30 -1 53
第2次排序结果:100 99 53 20 30 -1
第3次排序结果:100 99 53 30 20 -1
第4次排序结果:100 99 53 30 20 -1
第5次排序结果:100 99 53 30 20 -1
最终排序结果:100 99 53 30 20 -1
算法执行过程(正序):
空间效率:仅使用一个辅存单元(temp)。
时间效率:假设待排序的元素个数为 n,则总共要进行 n-1 趟排序,对 j 个元素的子序
列进行一趟起泡排序需要进行 j-1 次关键字比较。由此,起泡排序的总比较次数为
因此,起泡排序的时间复杂度为 O(n2) Ο ( n 2 ) 。
在计算机资源中,最重要的就是时间与空间。评价一个算法性能的好坏,实际上就是评价算法的资源占用问题。
一旦去掉表示算法运行时间中的低阶项和首项常数,就称我们是在度量算法的渐进时间复杂度(渐进时间复杂度(asymptotic complexity) ),简称 时间复杂度.
为了进一步说明算法的时间复杂度,定义 Ο、Ω、Θ符号。
比如时间复杂度为 O(n2) Ο ( n 2 )
这个符号可以解释为:只要当排序元素的个数大于某个阈值N时,那么对于某个常量c > 0,运行时间最多为c n2 n 2 。也就是说Ο符号提供了一个运行时间的上界。
Ο符号给出了算法时间复杂度的上界,而Ω符号在运行时间的常数因子范围内给出了时间复杂度的下界。
Ω符号可以解释为:如果输入大于等于某个阈值 N,算法的运行时间下限是 f(n)的 c 倍,其中 c 是一个正常数,则称算法的时间复杂度是Ω(f(n))的。Ω的形式定义与Ο符号对称。
Ο符号给出了算法时间复杂度的上界,Ω符号给出了时间复杂度的下界,而θ给出了算法时间复杂度的精确阶。
Θ符号可以解释为:如果输入大于等于某个阈值N,算法的运行时间在下限 c1 c 1 f(n)和上限
c2 c 2 f(n)之间(0< c1 c 1 ≤ c2 c 2 ),则称算法的时间复杂度是Θ(f(n))阶的。
我们评价算法的运行时间是通过分析在一定规模下算法
执行基本操作的次数来反映的,并且由于我们只对大规模问题的运行时间感兴趣,所以是使
用算法的渐进时间复杂度 T(n)来度量算法的时间性能的。Ο、Ω、Θ符号分别定义了时间复
杂度的上界、下界以及精确阶。
算法使用的空间定义为:为了求解问题的实例而执行的操作所需要的存储空间的数目,但是它不包括用来存储输入实例的空间。
/*
* 优化后写法
*/
public static void BubbleSort1(int [] arr){
System.out.print("要排序的数组:");
for (int a = 0; a < arr.length; a++) {
System.out.print(arr[a] + "\t");
}
System.out.println("");
int temp;//临时变量
boolean flag;//是否交换的标志
for(int i=0; i1; i++){ //表示排序次数,一共arr.length-1次。
flag = false;
for(int j=arr.length-1; j>i; j--){
if(arr[j] > arr[j-1]){
temp = arr[j];
arr[j] = arr[j-1];
arr[j-1] = temp;
flag = true;
}
}
if(!flag) break;
System.out.print("第" + (i + 1) + "次排序结果:");
for (int a = 0; a < arr.length; a++) {
System.out.print(arr[a] + "\t");
}
System.out.println("");
}
System.out.print("最终排序结果:");
for (int a = 0; a < arr.length; a++) {
System.out.print(arr[a] + "\t");
}
}
优化后的排序过程:
要排序的数组:100 20 30 -1 99 53
第1次排序结果:100 99 20 30 -1 53
第2次排序结果:100 99 53 20 30 -1
第3次排序结果:100 99 53 30 20 -1
最终排序结果:100 99 53 30 20 -1
总结:冒泡排序是比较重要的。一般面试都会问的。有必要掌握的。写博客是为了帮助开发者学习使用技术,同时巩固自己所学技术。如果此篇博客有助于您的学习,那是我的荣幸!如果此篇博客有任何瑕疵,请多多指教!在此感谢您的学习和指教!