冒泡排序、选择排序和插入排序的时间复杂度分析

一、冒泡排序

(1) 指向数组中两个相邻的元素(最开始是数组的头两个元素),比较它们的大小。

(2) 如果它们的顺序错了(即左边的值大于右边),就互换位置。

如果顺序已经是正确的,那这一步就什么都不用做。

(3) 将两个指针右移一格。

重复第(1)步和第(2)步,直至指针到达数组末尾。

(4)重复第(1)至(3)步,直至从头到尾都无须再做交换,这时数组就排好序了。 这里被重复的第(1)至(3)步是一个轮回,也就是说,这个算法的主要步骤被“轮回”执行, 直到整个数组的顺序正确。

以下是用 Python 写的冒泡排序。

def bubble_sort(list):
    unsorted_until_index = len(list) - 1
    sorted = False

    while not sorted:
        sorted = True
        for i in range(unsorted_until_index):
            if list[i] > list[i + 1]:
                sorted = False
                list[i], list[i + 1] = list[i + 1], list[i]
        unsorted_until_index = unsorted_until_index - 1

list = [65, 55, 45, 35, 25, 15, 10]
bubble_sort(list)
print (list)

 执行步骤:比较、交换

在最坏的情况下(即完全反序),需要进行(N - 1) + (N - 2) + (N - 3) + … + 1 次比较。

每次比较后,都要进行一次交换,随着 N 的增长,步数大约增长为 N^{2_{}}

 因此描述冒泡排序效率的大 O 记法,是 O(N^{2_{}})。 规范一些来说:用 O(N^{2_{}} )算法处理 N 个元素,大约需要 N^{2_{}}步。

二、选择排序

(1) 从左至右检查数组的每个格子,找出值最小的那个。在此过程中,我们会用一个变量来 记住检查过的数字的最小值(事实上记住的是索引,但为了看起来方便,下图就直接写出数值)。 如果一个格子中的数字比记录的最小值还要小,就把变量改成该格子的索引,如图所示。

(2) 知道哪个格子的值最小之后,将该格与本次检查的起点交换。第 1 次检查的起点是索引 0, 第 2 次是索引 1,以此类推。下图展示的是第一次检查后的交换动作。

(3) 重复第(1) (2)步,直至数组排好序。

以下是用 Javascript 写的选择排序。

function selectionSort(array)
{
    for (var i = 0; i < array.length(); i++)
    {
        var lowestNumberIndex = i;
        for (var j = i + 1; j < array.length(); j++)
        {
            if (array[j] < array[lowestNumberIndex])
            {
                lowestNumberIndex = j;
            }
        }
        if (lowestNumberIndex != i)
        {
            var temp = array[i];
            array[i] = array[lowestNumberIndex];
            array[lowestNumberIndex] = temp;
        }
    }
    return array;
}

大 O 记法忽略常数

因此描述选择排序效率的大 O 记法,是 O(N^{2_{}})  而非  O(N^{2_{}} / 2) 

三、插入排序

(1) 在第一轮里,暂时将索引 1 (第 2 格)的值移走,并用一个临时变量来保存它。这使得该索引处留下一个空隙,因为它不包含值。

在之后的轮回,我们会移走后面索引的值。

(2) 接着便是平移阶段,我们会拿空隙左侧的每一个值与临时变量的值进行比较。 如果空隙左侧的值大于临时变量的值,则将该值右移一格。

随着值右移,空隙会左移。如果遇到比临时变量小的值,或者空隙已经到了数组的最左 端,就结束平移阶段。

(3) 将临时移走的值插入当前空隙。 

(4) 重复第(1)至(3)步,直至数组完全有序。

以下是插入排序的 Python 实现。

def insertion_sort(array):
    for index in range(1, len(array)):

        position = index
        temp_value = array[index]

        while position > 0 and array[position - 1] > temp_value:
            array[position] = array[position - 1]
            position = position - 1

        array[position] = temp_value

 插入排序包含 4 种步骤:移除、比较、平移和插入。

比较的总次数为:1 + 2 + 3 + … + N - 1 次。

temp_value 的移除跟插入在每一轮里都会各发生一次。因为总是有 N - 1 轮,所以可以得出 结论:有 N - 1 次移除和 N - 1 次插入。

我们每次将值右移一格,就是平移操作。当数组完全逆序时,有多少次比较就要多少次平移, 因为每次比较的结果都会使你将值右移。

把最坏情况下的比较步数和平移步数相加。 N^{2_{}} / 2 次比较 + N^{2_{}} / 2 次平移 = N^{2_{}}

总共N^{2_{}}+ 2N - 2 步

大 O 只保留最高阶的 N。

因此描述插入排序效率的大 O 记法,是 O(N^{2_{}}

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值