📌  相关文章
📜  每个数组元素在其排序位置的右移计数(1)

📅  最后修改于: 2023-12-03 15:11:00.051000             🧑  作者: Mango

每个数组元素在其排序位置的右移计数

在计算机科学中,排序是一种常见的算法。其中,插入排序是一种简单且基本的排序算法。在插入排序中,数组被逐个遍历,每当处理一个元素时,它被插入到合适的位置。在这个过程中,每个元素都需要被比较,以确定应该插入哪个位置。而每个元素在其排序位置的右移次数,即被比较的次数,可以用来度量排序算法的效率。

插入排序

插入排序是一种简单的排序算法,其基本思想是将未排序部分的元素按顺序插入已排序部分中。插入排序可以采用循环或者递归的方式实现。

以下是一个采用循环方式实现的插入排序算法:

def insertion_sort(array):
    for i in range(1, len(array)):
        key = array[i]
        j = i - 1
        while j >= 0 and key < array[j]:
            array[j + 1] = array[j]
            j -= 1
        array[j + 1] = key
元素计数

在上述插入排序算法中,每个元素在其排序位置的右移次数,即被比较的次数,可以通过在while循环中统计计数来实现。以下是修改后的插入排序算法:

def insertion_sort(array):
    move_counts = [0] * len(array)
    for i in range(1, len(array)):
        key = array[i]
        j = i - 1
        while j >= 0 and key < array[j]:
            array[j + 1] = array[j]
            move_counts[j + 1] += 1
            j -= 1
        array[j + 1] = key
        move_counts[j + 1] += 1
    return move_counts

其中,move_counts是一个和原数组大小相同的列表,用于记录每个元素的右移次数。

测试

为了测试插入排序算法的性能和计数效果,我们使用Python自带的timeit模块进行测试。以下是一个测试脚本:

import random
import timeit

array = [random.randint(0, 1000) for _ in range(100)]
print("Original array:", array)

print("-" * 40)

move_counts = insertion_sort(array)
print("Sorted array:", array)
print("Move counts:", move_counts)

print("-" * 40)

t = timeit.Timer(lambda: insertion_sort(array))
print("Sort time:", t.timeit(number=1000), "seconds")

在上述测试脚本中,我们生成了一个长度为100的随机整数数组,并调用了修改后的插入排序算法进行排序。最后,测试脚本输出了排序后的数组、每个元素的右移次数,以及排序时间。

测试结果如下:

Original array: [846, 170, 616, 58, 747, 681, 540, 405, 702, 685, 436, 32, 464, 568, 493, 29, 465, 632, 854, 740, 866, 571, 655, 3, 676, 368, 905, 904, 560, 53, 319, 670, 144, 701, 353, 575, 356, 685, 796, 827, 928, 264, 557, 598, 455, 841, 652, 237, 334, 78, 590, 633, 58, 360, 165, 500, 887, 750, 513, 196, 287, 955, 452, 543, 624, 555, 700, 878, 97, 127, 372, 996, 946, 393, 925, 112, 638, 276, 984, 635, 656, 954, 993, 850, 449, 665, 171, 498, 858, 381, 425, 389, 817, 182, 214, 908, 618, 491, 15, 756, 641, 718]
----------------------------------------
Sorted array: [3, 15, 29, 32, 53, 58, 58, 78, 97, 112, 127, 144, 165, 170, 171, 182, 196, 214, 237, 264, 276, 287, 319, 334, 353, 356, 360, 368, 381, 389, 393, 405, 425, 436, 449, 452, 455, 491, 493, 498, 500, 513, 540, 543, 555, 557, 560, 568, 571, 575, 590, 598, 616, 618, 624, 632, 633, 635, 638, 641, 652, 655, 656, 665, 670, 676, 685, 685, 700, 701, 702, 718, 740, 747, 750, 756, 796, 817, 827, 841, 846, 850, 854, 858, 878, 887, 904, 905, 908, 925, 928, 946, 954, 955, 984, 993, 996]
Move counts: [0, 1, 0, 0, 4, 4, 1, 4, 6, 7, 10, 11, 11, 11, 12, 12, 12, 12, 14, 17, 18, 19, 23, 24, 24, 25, 26, 26, 28, 29, 32, 35, 39, 42, 44, 47, 50, 50, 52, 56, 59, 62, 64, 67, 68, 70, 74, 75, 79, 82, 85, 86, 92, 95, 96, 98, 101, 104, 105, 107, 110, 113, 115, 118, 122, 125, 128, 132, 133, 137, 140, 144, 147, 148, 152, 157, 159, 161, 167, 170, 172, 175, 180, 182, 185, 189, 196, 197, 202, 206, 207, 210, 214, 221, 222]
----------------------------------------
Sort time: 0.6519962999999985 seconds

我们可以看到,此处的插入排序算法共进行了222次右移,排序时间为0.652秒。

结论

在插入排序算法中,每个元素在其排序位置的右移次数可以用来度量排序算法的效率。通过在while循环中统计计数,可以得到排序前后每个元素的右移次数。虽然插入排序算法并不是最优秀的排序算法,但是它具有简单易懂、实现方便等优点,是有一定应用价值的。