经典排序算法--冒泡排序

冒泡排序的基本思想:

在要排序的一组数中,对当前还未排好序的范围内的全部数,自上而下对相邻的两个数依次进行比较和调整,让较大 的数往下沉 ,较小的往上冒。即:每当两相邻的数比较后发现它们的排序与排序要求相反时,就将它们互换。

关于程序中4中冒泡排序写法的说明:

bubble_sort1:基本的冒泡排序的写法。

bubble_sort2:基本冒泡排序的不同写法,基本的冒泡排序是每次遍历,每次缩小范围1,这种办法是每次正向和反向遍历,每次缩小范围2,所以两者的比较次数也是一样的。

bubble_sort3:如果在某一趟的冒泡途中没有出现数据交换,那就只能是数据已经被排好序了,这样就可以提前得知数据排好序从而中断循环,消除掉不必要的比较。

bubble_sort4:如果在某一趟的冒泡途中最后的交换出现在pos的位置,那么表示pos位置以后都已经排好序,这样相比于基本冒泡每一次缩小遍历范围1而言有可能一次缩小的遍历范围>=1,所以这样也可以提高排序的效率。

程序代码如下:

  1 package mecrt.study.collection.sort;
  2
  3 /**
  4  * 冒泡排序
  5  */
  6 public class BubbleSort {
  7     public static void main(String[] args) {
  8
  9         int[] a = {3,5,1,2,4,9,6,8,10,7};
 10         int[] b = {3,5,1,2,4,9,6,8,10,7};
 11         int[] c = {3,5,1,2,4,9,6,8,10,7};
 12         int[] d = {3,5,1,2,4,9,6,8,10,7};
 13         System.out.println("\n初始值:");
 14         print(a);
 15         int count1 = dubbleSort1(a);
 16         System.out.println("排序后:");
 17         print(a);
 18         System.out.println("dubbleSort1比较次数"+count1);
 19
 20
 21         System.out.println("\n初始值:");
 22         print(b);
 23         int count2 = dubbleSort2(b);
 24         System.out.println("排序后:");
 25         print(b);
 26         System.out.println("dubbleSort2比较次数"+count2);
 27
 28         System.out.println("\n初始值:");
 29         print(c);
 30         int count3 = dubbleSort3(c);
 31         System.out.println("排序后:");
 32         print(c);
 33         System.out.println("dubbleSort3比较次数"+count3);
 34
 35         System.out.println("\n初始值:");
 36         print(d);
 37         int count4 = dubbleSort4(d);
 38         System.out.println("排序后:");
 39         print(d);
 40         System.out.println("dubbleSort4比较次数"+count4);
 41     }
 42
 43     /**
 44      * 最基本的冒泡排序
 45      * @param data
 46      */
 47     public static int dubbleSort1(int[] data){
 48         int count = 0;
 49         //冒泡一次放好一个数,冒泡data.length-1次,数组排序完成
 50         for (int i = 0; i < data.length-1; i++) {
 51             //后面i个数已经冒泡完成,为有序数列,不需要再次进行冒泡
 52             for (int j = 0; j < data.length-1-i; j++,count++) {
 53                 //相邻元素想比较,进行冒泡
 54                 if(data[j]>data[j+1]){
 55                     swap(data, j, j+1);
 56                 }
 57             }
 58         }
 59         return count;
 60     }
 61
 62     /**
 63      * 双向冒泡排序
 64      *  @param data
 65      */
 66     public static int dubbleSort2(int[] data){
 67         int low = 0;
 68         int high = data.length-1;
 69         int j,count=0;
 70         while(low<high){
 71             for (j=low; j < high; j++, count++) {
 72                 if(data[j]>data[j+1]){
 73                     swap(data, j, j+1);
 74                 }
 75             }
 76             high--;
 77             for (j = high; j > low; j--,count++) {
 78                 if(data[j]<data[j-1]){
 79                     swap(data, j, j-1);
 80                 }
 81             }
 82             low++;
 83         }
 84         return count;
 85     }
 86
 87     /**
 88      * 冒泡排序,如果在某一趟的冒泡途中没有出现数据交换,
 89      * 那就只能是数据已经被排好序了,
 90      * 这样就可以提前得知数据排好序从而中断循环,
 91      * 消除掉不必要的比较。
 92      * @param data
 93      * @return
 94      */
 95     public static int dubbleSort3(int[] data){
 96         int i,j,count = 0;
 97         boolean exchange = true;
 98         for (i = 0; i < data.length-1&&exchange; i++) {
 99             for (j = 0,exchange = false; j < data.length-1-i; j++,count++) {
100                 if(data[j]>data[j+1]){
101                     swap(data, j, j+1);
102                     exchange = true;
103                 }
104             }
105         }
106         return count;
107     }
108
109     /**
110      * 如果在某一趟的冒泡途中最后的交换出现在pos的位置,
111      * 那么表示pos位置以后都已经排好序,
112      * 这样相比于基本冒泡每一次缩小遍历范围1而言有可能一次缩小的遍历范围>=1,
113      * 所以这样也可以提高排序的效率。
114      * @param data
115      * @return
116      */
117     public static int dubbleSort4(int[] data){
118         int i,j,pos = 0,count = 0;
119         for (i = 0; i < data.length-1; i = data.length - 1 - pos) {
120             for (j = 0,pos = 0; j < data.length-1-i; j++,count++) {
121                 if(data[j]>data[j+1]){
122                     swap(data, j, j+1);
123                     pos = j+1;
124                 }
125             }
126         }
127         return count;
128     }
129     public static void swap(int[] data,int i,int j){
130         if(i == j ){
131             return ;
132         }
133         data[i] = data[i] + data[j];
134         data[j] = data[i] - data[j];
135         data[i] = data[i] - data[j];
136     }
137
138     private static void print(int[] a){
139         for (int i = 0; i < a.length; i++) {
140             System.out.print(a[i]+"  ");
141         }
142         System.out.println();
143     }
144 }

运行结果:

初始值:
3  5  1  2  4  9  6  8  10  7
排序后:
1  2  3  4  5  6  7  8  9  10
dubbleSort1比较次数45

初始值:
3  5  1  2  4  9  6  8  10  7
排序后:
1  2  3  4  5  6  7  8  9  10
dubbleSort2比较次数45

初始值:
3  5  1  2  4  9  6  8  10  7
排序后:
1  2  3  4  5  6  7  8  9  10
dubbleSort3比较次数30

初始值:
3  5  1  2  4  9  6  8  10  7
排序后:
1  2  3  4  5  6  7  8  9  10
dubbleSort4比较次数33

冒泡排序法的特点:

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

空间复杂度:O(1)

稳定性:稳定

时间: 2024-12-05 03:42:33

经典排序算法--冒泡排序的相关文章

经典排序算法 - 冒泡排序Bubble sort

 原文出自于 http://www.cnblogs.com/kkun/archive/2011/11/23/bubble_sort.html 经典排序算法 - 冒泡排序Bubble sort 原理是临近的数字两两进行比较,按照从小到大或者从大到小的顺序进行交换, 这样一趟过去后,最大或最小的数字被交换到了最后一位, 然后再从头开始进行两两比较交换,直到倒数第二位时结束,其余类似看例子 例子为从小到大排序, 原始待排序数组| 6 | 2 | 4 | 1 | 5 | 9 | 第一趟排序(外循环) 第

吴裕雄--天生自然数据结构:十大经典排序算法——冒泡排序

冒泡排序 冒泡排序(Bubble Sort)也是一种简单直观的排序算法.它重复地走访过要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来.走访数列的工作是重复地进行直到没有再需要交换,也就是说该数列已经排序完成.这个算法的名字由来是因为越小的元素会经由交换慢慢"浮"到数列的顶端. 作为最简单的排序算法之一,冒泡排序给我的感觉就像 Abandon 在单词书里出现的感觉一样,每次都在第一页第一位,所以最熟悉.冒泡排序还有一种优化算法,就是立一个 flag,当在一趟序列遍历中

经典排序算法——冒泡排序

对于一个int数组,请编写一个冒泡排序算法,对数组元素排序. 给定一个int数组A及数组的大小n,请返回排序后的数组. 测试样例: 输入数组:[1,2,3,5,2,3],6 输出数组:[1,2,2,3,3,5] class BubbleSort { public: int* bubbleSort(int* A, int n) { // write code here bool flag=true; for(int i=0;i<n && flag;++i) { for(int j=n-

经典排序算法

经典排序算法(via  kkun) 经典排序算法,以下文章参考了大量网上的资料,大部分都给出了出处 这一系列重点在理解,所以例子什么的都是最简单的情况,难免失误之处,多指教 大多数排序算法都给出了每一步的状态,以方便初学者更容易理解,通俗易懂,部分难以理解的排序算法则给出了大量的图示,也算是一个特色吧 经典排序算法 - 快速排序Quick sort 经典排序算法 - 桶排序Bucket sort 经典排序算法 -  插入排序Insertion sort 经典排序算法 - 基数排序Radix so

【转】经典排序算法

地址:http://www.cnblogs.com/kkun/archive/2011/11/23/2260312.html 大多数排序算法都给出了每一步的状态,以方便初学者更容易理解,通俗易懂,部分难以理解的排序算法则给出了大量的图示,也算是一个特色吧 经典排序算法 - 快速排序Quick sort 经典排序算法 - 桶排序Bucket sort 经典排序算法 -  插入排序Insertion sort 经典排序算法 - 基数排序Radix sort 经典排序算法 - 鸽巢排序Pigeonho

经典排序算法【转】

转自 还有多少青春可以挥霍 经典排序算法 - 快速排序Quick sort 经典排序算法 - 桶排序Bucket sort 经典排序算法 -  插入排序Insertion sort 经典排序算法 - 基数排序Radix sort 经典排序算法 - 鸽巢排序Pigeonhole sort 经典排序算法 - 归并排序Merge sort 经典排序算法 - 冒泡排序Bubble sort 经典排序算法 - 选择排序Selection sort 经典排序算法 - 鸡尾酒排序Cocktail sort 经

经典排序算法1--冒泡排序

/* 经典排序算法--冒泡排序 1.从小到大排序. #include<stdio.h> int main() { int n,a[100],i,j,t; printf("请输入要排序的元素个数:"); while(scanf("%d",&n)) { printf("请输入要排序的元素: "); for(i=0;i<n;i++) { scanf("%d",&a[i]); } //排序次数,最多需

[经典排序算法][集锦]

http://www.cnblogs.com/kkun/archive/2011/11/23/2260312.html 经典排序算法 经典排序算法,以下文章参考了大量网上的资料,大部分都给出了出处 这一系列重点在理解,所以例子什么的都是最简单的情况,难免失误之处,多指教 大多数排序算法都给出了每一步的状态,以方便初学者更容易理解,通俗易懂,部分难以理解的排序算法则给出了大量的图示,也算是一个特色吧 经典排序算法 - 快速排序Quick sort 经典排序算法 - 桶排序Bucket sort 经

C#实现所有经典排序算法

C# 实现所有经典排序算法 1 .选择排序 选择排序 原理: 选择排序是从冒泡排序演化而来的,每一轮比较得出最小的那个值,然后依次和每轮比较的第一个值进行交换. 目的:按从小到大排序. 方法:假设存在数组:72, 54, 59, 30, 31, 78, 2, 77, 82, 72 第一轮依次比较相邻两个元素,将最小的一个元素的索引和值记录下来,然后和第一个元素进行交换. 如上面的数组中,首先比较的是72,54,记录比较小的索引是54的索引1.接着比较54和59,比较小的索引还是1.直到最后得到最