算法2.1 选择排序

69 阅读2分钟

  一种最简单的排序算法是这样的:首先,找到数组中最小的那个元素,其次,将它和数组的第 一个元素交换位置(如果第一个元素就是最小元素那么它就和自己交换)。再次,在剩下的元素中 找到最小的元素,将它与数组的第二个元素交换位置。如此往复,直到将整个数组排序。这种方法 叫做选择排序,因为它在不断地选择剩余元素之中的最小者。

命题A
对于长度为 N 的数组,选择排序需要大约 N2 /2 次比较和 N 次交换。
证明。可以通过算法的排序轨迹来证明这一点。我们用一张 N×N 的表格来表示排序的轨迹,
其中每个非灰色字符都表示一次比较。表格中大约一半的元素不是灰色的——即对角线和其上部
分的元素。对角线上的每个元素都对应着一次交换。通过查看代码 我们可以更精确地得到,0 到 N-1 的任意 i 都会进行一次交换和 N-1-i 次比较,因此总共有 N 次交换以及 (N-1)+(N-2)+...+2+1=N(N-1)/2 ~ N2 /2 次比较。

image.png

image.png

排序算法基类
base.py

class SortBase(object):
    """
    排序算法基类
    """

    @classmethod
    def less(cls, a, b) -> bool:
        """
        比较大小
        :param a:
        :param b:
        :return: True | False
        """
        return a < b

    @classmethod
    def exch(cls, a: list, index_1: int, index_2: int) -> None:
        """
        交换数字两元素位置
        :param a:
        :param index_1: 元素1索引
        :param index_2: 元素2索引
        :return:
        """
        a[index_1], a[index_2] = a[index_2], a[index_1]

    @classmethod
    def isSorted(cls, a: list) -> bool:
        """
        判断是否成功排序
        :param a: 数组
        :return:
        """
        if len(a) < 2:
            return True
        for index in range(len(a) - 1):
            if not cls.less(a[index], a[index + 1]):
                return False
            return True

选择排序算法
Selection.py

from base import SortBase


class Selection(SortBase):
    @classmethod
    def sort_fn(cls, a: list) -> list:
        n = len(a)
        for index in range(n):
            min_attr = index
            for idx in range(index + 1, n):
                if cls.less(a[idx], a[min_attr]):
                    min_attr = idx
            if min_attr != index:
                cls.exch(a, index_1=index, index_2=min_attr)
        return a


if __name__ == '__main__':
    a = [2, 32, 242, 54, 5, 3, 25, 6, 7, 31, 4, 556, 89]
    sort_a = Selection.sort_fn(a)
    print(sort_a)
    print(Selection.isSorted(a))