数据结构学习3:选择排序和快速排序原理及Python实现 归并排序和希尔排序的基本思想

归并排序和希尔排序的基本思想

简单排序之冒泡排序和插入排序原理及实现


1. 选择排序

(1)原理:首先在未排序的序列里找到最小(大)元素,放到序列的首端,再从剩余元素中找到最小(大)的元素,放到序列的尾端。依次循环,直到排序完成。

(2)时间复杂度:选择排序交换此处是处于0-(n-1)次之间,需要比较n(n-1) / 2次,赋值操作次数在0-3(n-1)次之间,因此平均时间复杂度为O(n**2)

(3)空间复杂度:算法的空间复杂度并不是计算实际占用的空间,而是计算整个算法的辅助空间单元的个数,与问题的规模没有关系。算法的空间复杂度S(n)定义为该算法所耗费空间的数量级。选择排序只是元素交换是占用了定量的空间,与N无关,空间复杂度为O(1),即为常数。

(4)Python实现代码

# 非递归实现
def selectSorting(myList):
    "选择排序,接收一个数组或列表,每次找出最小的元素放在最前面,下一次循环就可以不考虑已经选好的最小元素"
    k = 0   # 计数器,测试使用,每交换一次元素,k值加1
    for i in range(len(myList)-1):
        temp = myList[i]        # 保存第i个数据,以备后面进行元素值交换
        min_val = myList[i]     # 设第i个数为最小
        min_val_idx = i
        for j in range(i+1,len(myList)):
            if myList[j] < min_val:    # 寻找最小数据
                min_val = myList[j]
                min_val_idx = j

        # 找到最小数据后,交换第i个数和第min_val_idx个数
        if i != min_val_idx:
            k += 1
            myList[i] = min_val
            myList[min_val_idx] = temp
    print("非递归选择排序共进行了",k,'次交换')
    return myList

list1 = [2,83,4,5,1,7,6,99,87,100]
print(selectSorting(list1))

非递归选择排序共进行了 4 次交换
[1, 2, 4, 5, 6, 7, 83, 87, 99, 100]


2. 快速排序

(1)原理:快速排序的基本思想就是从一个数组中任意挑选一个元素(通常来说会选择最左边的元素)作为基准数,将剩下的元素和基准数进行比较,将小于等于中轴元素的放到基准数的左边,将大于中轴元素的放到基准数的右边,然后以当前基准数的位置为界,将左半部分子数组和右半部分子数组看成两个新的数组,重复上述操作,直到子数组的元素个数小于等于1。

(2)时间复杂度:在最优的情况下,快速排序算法的时间复杂度为O(nlogn),最糟糕的情况下是O(n**2)

 (3) Python实现代码: key的选择可以优化
g2n
#  递归实现
def fastSorting(myList,left,right):
    """myList ---- 将要被排序的列表
       left --- 记录列表的起始位置
       right --- 记录列表的末尾位置
       每次循环要将小于key的数字放在key左边,大于key的数字放在key的右边
       """

    if left < right:
        key = myList[left]    # 初始时选择列表的第一个数字作为基准数
        i = left+1; j = right   # i是从左扫描的位置,j是从右扫描的位置

        while i <= j:
            while i <= j and myList[j] > key :
                j -= 1      # 从后面开始找,找到比key值小的数为止
            while i <= j and myList[i] <= key:
                i += 1    # 从前面开始找,找到比key值大的数为止

            if i < j:
                temp = myList[i]
                myList[i] = myList[j]  # 将该数放到key值的左边
                myList[j] = temp #将该数放到key值的右边
                i += 1    # 每次完成交换,左侧扫描的位置向右移动一位,右侧扫描的位置向左移动一位
                j -= 1

        # 当循环结束时,j指向的元素是最后一个(从左边算起)小于等于key的元素
        myList[left] =  myList[j]
        myList[j] = key               # 把key值填充到left位置,下次重新找key值

        fastSorting(myList,left,j-1)    #递归左半部分
        fastSorting(myList,j+1,right)   #递归右半部分
    return myList

myList = [12,83,4,5,1,7,6,99,87,100]
fastSorting(myList,0,len(myList)-1)
print(myList)

[1, 4, 5, 6, 7, 12, 83, 87, 99, 100]


猜你喜欢

转载自blog.csdn.net/zhuzuwei/article/details/80589943
今日推荐