【算法分析】冒泡排序法

  今天突然心血来潮了,想开始看算法了,立此博文,开始对算法系列开始完善,争取每周两文。在分析过程中可能想法较笨,希望各位能够宽容和帮助,如果有更好的意见和建议,可随时留言批评。闲话少数,开始正文。
第一次程序
// 通过一次循环将数组中第一个数安排到数组中比它小的数之前
for (int i = 0; i < test.Length - 1; i++) // 此处不能为test.Length,数组溢出。说明从头到尾交换的最大次数 = 数组元素个数 - 1
{
    if (test[i] < test[i + 1])
    {
        int temp = test[i + 1];
        test[i + 1] = test[i];
        test[i] = temp;
    }
}

 

继续
/* 
    遍历数组个数的次数,对上面内层数据交换进行循环,即可得到排序后的数组。其实仔细想想,外层的循环次数可以是任意的数,因为只要内层将所有的数据都进行了排序即可。但是,即使是没有次数的限制,也要有一个最低的次数选择,假设外层为j < 1这样只循环一次,你觉得程序会得到正确的结果么?所以,你会如何选择这个值?
    不防想想,现在数组中有n个元素,将整个数组的元素倒置过来,并且只能相邻两个元素交换位置(比如当前为{1,3,2},倒置为{2,3,1})需要多少次,用最笨的枚举法可知为n*(n-1)/2,而得到的这个次数即为内层循环与外层循环的总次数,并且这个次数即为最坏打算的排序的次数,何为最坏打算,就是数组中的元素为从小到大排列,而最后得到的结果为从大到小排列。因此根据之前分析,可得到如下核心程序。
*/
for (int j = 0; j < test.Length; j++)
{
    for (int i = 0; i < test.Length - 1 - j; i++)
    {
        if (test[i] < test[i + 1])
        {
            int temp = test[i + 1];
            test[i + 1] = test[i];
            test[i] = temp;
        }
    }
}
/*
    分析如上程序,外层循环了n次的内层程序,而每一次内层程序循环的次数和外层有线性关系,如j = 0时,内部程序循环test.Length - 1次,j = 1时,内部程序循环了test.Length - 2次,而当j = test.Length - 1时,内部程序循环了0次,一共循环了(test.Length - 1 + 0)【内层】* test.Length【外层】 / 2次,即n * (n - 1) / 2次,正如上所述。
    问题来了,之前分析的当j = test.Length - 1时,内部循环了0次,说明未走到内部的数值交换处理中,那么如何解决此问题?请看第二次的程序。
*/

 

第二次程序
/*
    如果保证内层循环有效,即内层的最后一次循环次数不为0,为1,则test.Length - j - 1 = 1那么,外层循环的最大次数j = test.Length - 2,因此外部循环的范围是[0,test.Length - 1)
*/
for (int j = 0; j < test.Length - 1; j++)
{
    for (int i = 0; i < test.Length - j - 1; i++)
    {
        if (test[i] < test[i + 1])
        {
            int temp = test[i + 1];
            test[i + 1] = test[i];
            test[i] = temp;
        }
    }
}

 

总结
  以上便是我对冒泡排序法的层层分析总结,并且通过总结,可知冒泡排序算法的时间复杂度为O(n的平方)。如果有什么建议或则发现什么错误可提出,欢迎大家指正。先谢谢各位了!

 

posted @ 2015-04-28 00:30  DemoZhang  阅读(1791)  评论(0编辑  收藏  举报