码迷,mamicode.com
首页 > 编程语言 > 详细

冒泡排序

时间:2015-12-08 22:18:01      阅读:315      评论:0      收藏:0      [点我收藏+]

标签:

冒泡排序是一种交换排序,它的基本思想是:两两比较相邻记录的关键字,如果反序则交换,直到没有反序为止

稳定性:冒泡排序是稳定排序

时间复杂度: 最好:O(n)   最差:O(n^2)  平均:O(n^2)

辅助空间:O(1)

 

以下的所有代码都要用到的swap函数在此给出

技术分享
/*实现swap功能*/
void swap(int *a, int *b){
    *a ^= *b;
    *b ^= *a;
    *a ^= *b;
}
View Code

下面先看一段最简单的排序代码,从严格意义上说,它不算是标准的冒泡排序算法,因为它不满足 “两两比较相邻记录” 的冒泡排序思想,它更应该是最简单的交换排序而已。

交换排序的数组版本:

技术分享
/* 对顺序表作交换排序(冒泡排序初级版) --- 数组版*/
void BubbleSort11(int *L, int n){
    //注意下标从0开始
    for (int i = 0; i < n - 1; ++i){
        for (int j = i + 1; j < n; ++j){
            if (L[j] < L[i]){
                //其实是简单选择排序的记录位置改成了直接交换,因此此版本的冒泡排序是不稳定排序
                swap(L + i, L + j); 
            }
        }//for(j)
    }//for(i)
}
View Code

交换排序的指针版本:

技术分享
/* 对顺序表作交换排序(冒泡排序初级版) --- 指针版*/
/* [head,tail)为左闭又开区间*/
void BubbleSort12(int *head, int *tail){
    for (int* p = head; p < tail - 1; ++p){
        for (int* q = p + 1; q < tail; ++q){
            if (*q < *p){
                swap(p, q);
            }
        }//for(q)
    }//for(p)
}
View Code

 

接下来便是正宗的冒泡排序算法,由于冒泡排序既可以从前往后冒泡,又可以从后往前冒泡,于是实现了从前往后冒泡和从后往前冒泡的数组、指针共4种版本。

技术分享
/* 冒泡排序算法 --- 数组版(采用从后往前冒泡)*/
void BubbleSort21(int *L, int n){
    for (int i = 0; i < n - 1; ++i){
        for (int j = n - 1; j > i; --j){
            if (L[j] < L[j - 1])
                //若后者小于前者,前移
                swap(L + j, L + j - 1);
        }//for(j)
    }//for(i)
}
View Code
技术分享
/* 冒泡排序算法 --- 数组版(采用从前往后冒泡)*/
void BubbleSort22(int *L, int n){
    for (int i = n - 1; i > 0; --i){
        for (int j = 0; j < i; ++j){
            if (L[j] > L[j + 1]){
                //若前者大于后者
                swap(L + j, L + j + 1);
            }
        }//for(j)
    }//for(i)
}
View Code
技术分享
/* 冒泡排序算法 --- 指针版(采用从后往前冒泡)*/
/* 同理,[head, tail)为左闭右开区间 */
void BubbleSort23(int* head, int* tail){
    for (int *p = head; p < tail - 1; ++p){
        for (int *q = tail - 1; q > p; --q){
            if (*q < *(q - 1)){
                //后者小于前者,小的往前冒泡
                swap(q, q - 1);
            }
        }//for(q)
    }//for(p)
}
View Code
技术分享
/* 冒泡排序算法 --- 指针版(采用从前往前后冒泡)*/
/* [head, tail)为左闭右开区间 */
void BubbleSort24(int* head, int* tail){
    for (int* p = tail - 1; p > head; --p){
        for (int* q = head; q < p; ++q){
            if (*q > *(q + 1)){
                //若前者大于后者,大的往后冒泡
                swap(q, q + 1);
            }
        }//for(q)
    }//for(p)
}
View Code

 

其实,以上的冒泡排序是可以优化的,如序列{2,1,3,4,5,6,7,8,9}只需交换第一、第二的关键字,别的都已经是正常的顺序。 因此第一次交换后,数据已经有序,此后的大量比较是多余的,那如何优化呢? 我们可以增加一个标记变量flag,用于标记序列是否已经有序,详见代码。

改进冒泡排序算法之数组版,从后往前冒泡

技术分享
/* 改进的冒泡排序算法 --- 数组版(从后往前冒泡) */
void BubbleSort31(int* L, int n){
    bool flag = true; //最开始是为了进入循环
    for (int i = 0; i < n - 1 && flag; ++i){
        flag = false; //初始化为false,若下面的循环未做更改,则数列已经有序,退出循环
        for (int j = n - 1; j > i; --j){
            if (L[j] < L[j - 1]){
                //若后者小于前者,小的往前冒泡
                swap(L + j, L + j - 1);
                flag = true; //更好做标记
            }
        }//for(j)
    }//for(i)
}
View Code

改进的冒泡排序算法之指针版,从前往后冒泡

技术分享
/* 改进冒泡排序 --- 指针版(从前往后冒泡)*/
void BubbleSort32(int* head, int* tail){
    bool flag = true;
    for (int* p = tail - 1; p > head && flag; --p){
        flag = false; //若下面的循环没有交换,则已经是有序序列,退出循环
        for (int* q = head; q < p; ++q){
            if (*q > *(q + 1)){
                //若前者大于后者,从后往前冒泡
                swap(q, q + 1);
                flag = true;
            }
        }//for(q)
    }//for(p)
}
View Code

 

冒泡排序

标签:

原文地址:http://www.cnblogs.com/tommychok/p/5030950.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!