交换排序之冒泡排序

基本原理:

  对一元素个数为n的数列进行扫描,同时逐一比较相邻的两个元素,按照所需的排序原则(顺序或逆序)对不满足要求的一组元素进行置换,一次扫描可以在得出一个当次扫面元素中最大或者最小的元素,然后对剩下的n-1个元素再进行同样的扫描与比较。在进行了n-1次扫描后,得到最终排好序的数列。因此冒泡排序的时间复杂度为o(n*n)。

基本实现:

  按照冒泡排序的思想,实现如下:

bool BubbleSort(int arrData[], int n)
{
    if(!arrData || n <= 0)
        return false;
    for(int i = 0; i < n-1; ++i)
    {
        for(int j = n-1; j > i; --j)            //为更形象的贴近冒泡的含义,进行逆序扫描,
        {                                       //使得每次扫描将最小的值放置在数组的最前端
            if(arrData[j-1] > arrData[j])
            {
                int temp = arrData[j];
                arrData[j] = arrData[j-1];
                arrData[j-1] = temp;
            }
        }
    }
    return true;
}


改进实现一:

  在基本实现中,只是根据数列的元素个数,按照原理机械的进行循环比较,没有考虑到过程中数列的状态,比如可能数列在结束循环之前,已经达到了要求的效果,但是还在进行没有必要的循环,因此造成效率上的损失。所以进行了如下改进,具体思想是,如果在某一次扫描过程中,没有发生一次置换操作,则实际数列已经排序完成。此时可以跳出循环,结束操作。

bool BubbleSortEx1(int arrData[], int n)
{
    if(!arrData || n <= 0)
        return false;
    bool bSwaped = true;
    for(int i = 0; i < n-1; ++i)
    {
        bSwaped = false;
        for(int j = n-1; j > i; --j)
        {
            if(arrData[j-1] > arrData[j])
            {
                int temp = arrData[j];
                arrData[j] = arrData[j-1];
                arrData[j-1] = temp;
                bSwaped = true;
            }
        }
        if(!bSwaped)
            break;
    }
    return true;
}


改进实现二:

  在”改进实现一“中,只是对外面的for循环做了优化,在一定条件下减少了外面for循环的次数。但是对于内部的for循环,依旧是进行机械式的操作。假设如下情况:某次扫描需要对n个元素进比较,内部的for要循环n-1次,但实际发现从第j次开始,就没有发生置换了。也就是说从数列的第j到第n个元素,已经排序好了。但是如果进行机械式的处理,在下一次扫描时,还是会对j到n-1之间的元素进行扫描,但这些元素已经排序好了,只是进行了无意义的操作,同样影响了效率。因此有了如下改进:

bool BubbleSortEx2(int arrData[], int n)
{
    if(!arrData || n <= 0)
        return false;
    int i = 0;
    while(i < n-1)
    {
        int pos = n-1;
        for(int j = n-1; j > i; --j)
        {
            if(arrData[j-1] > arrData[j])
            {
                int temp = arrData[j];
                arrData[j] = arrData[j-1];
                arrData[j-1] = temp;
                pos = j;
            }
        }
        i = pos;
    }
    return true;
}

  以上实现增加了一个pos变量用来记录每次扫描最后一次发生置换时的元素编号,那么对于下一次扫描,此编号之前的数列已经排序好了。所以只需要扫描n-1到pos之间的元素即可。当pos等于n-1时,表示数列全部排序完毕,跳出while循环。

 

posted on 2015-05-06 15:16  MoZhao  阅读(142)  评论(0编辑  收藏  举报

导航