数据结构与算法-- 栈与队列,排序算法稳定性,冒泡,选择,插入,希尔排序

本文介绍了栈和队列的基本概念,强调了它们的特性:栈是后进先出(LIFO),而队列是先进先出(FIFO)。接着讨论了排序算法的稳定性,以及四种经典的排序算法:冒泡排序、选择排序、插入排序和希尔排序的工作原理和时间复杂度。冒泡排序和选择排序的时间复杂度为O(n²),插入排序同样为O(n²),而希尔排序的时间复杂度为O(n^(1.3—2))。
摘要由CSDN通过智能技术生成

栈与队列的概念

栈(stack ):是一种容器,可存入数据元素、访问元素、删除元素,它的特点在于只能允许在容器的一端进行加入(push)数据和输出(pop)数据的运算。没有了位置概念,保证任何时候可以访问、删除的元素都是此前最后存入的那个元素,确定了一种默认的访问顺序(先进后出

在这里插入图片描述
在这里插入图片描述

队列(queue):只允许在一端进行插入操作,而在另一端进行删除操作的线性表
队列是一种先进先出的线性表,允许插入的一端为队尾,允许删除的一端为队头。队列不允许在中间部位进行操作!

排序算法的稳定性

定义:稳定排序算法会让原本相等的键值的记录维持相对次序,也就是如果一个排序算法是稳定的,当有两个相等键值的记录R和S,且在原本列表中R出现在S之前,在排序过的列表中R也将会使在S之前。
在这里插入图片描述

冒泡排序

思路:如果是从小→大排序,则两两比较,大的放后面,这样一轮下来,总是最大的放在最后,如果是含有n个元素的数组,则进行n-1轮。
根据下面代码可知:冒泡排序的时间复杂度为→O(n²)

def bubble_sort(alist):
    """冒泡排序"""
    n=len(alist)
    for j in range(0, n - 1):
        for i in range(0, n - 1 - j):
            if alist[i] > alist[i + 1]:
                alist[i], alist[i + 1] = alist[i + 1], alist[i]



li=[2,6,7,4,34,323,6,7,8,6]

bubble_sort(li)
print(li)

输出:

[2, 4, 6, 6, 6, 7, 7, 8, 34, 323]

Process finished with exit code 0

选择排序

思路:如果从小→大排序,在乱序的数组中,初始时,设置第一个元素为最小,让它与后面所有元素进行比较,如果遇到比第一个元素小的则进行交换,如此下来,最小的元素总是在前面,如果数组有n个元素,则进行n-1轮.
根据下面代码可知:选择排序的时间复杂度为→O(n²)

def select_sort(alist):
    n=len(alist)
    for j  in range(n-1):
        min_index=j
        for i in range(j,n-1):
            if alist[i] < alist[min_index]:
                alist[i],alist[min_index]=alist[min_index],alist[i]




li=[1,23,4,4,56,7,2,67]
select_sort(li)
print(li)

输出:

[1, 2, 4, 4, 7, 23, 56, 67]

Process finished with exit code 0

插入排序

思路:如果从小→大排序,将乱序的数组从逻辑上分为左边和右边,左边为有序,右边为乱序,一开始左边只有一个元素(也就是第一个元素),再从右边的数组中(右边数组从第二个开始),按次序抽出来,放到右边数组进行排序(从右边最后一个元素开始比较,谁小谁放前面,直到第一个),这样算一轮,如此下来,含有n个元素的数组,需要进行n-1轮

根据下面代码可知:插入排序的时间复杂度为→O(n²)

def insert_sort(alist):
    n = len(alist)
    for j in range(1, n):
        i = j
        while i > 0:
            if alist[i] < alist[i - 1]:
                alist[i], alist[i - 1] = alist[i - 1], alist[i]
                i -= 1
            else:
                 break

if __name__ == "__main__":
    li = [5, 55, 33, 44, 66, 11]
    print(li)
    insert_sort(li)
    print(li)

输出:

[5, 55, 33, 44, 66, 11]
[5, 11, 33, 44, 55, 66]

Process finished with exit code 0

希尔排序

思路: 希尔排序可以说是插入排序的升级版,首先它将乱序数组以一定的间隔分成多个子数组(逻辑上的),然后在各个子数组进行插入排序,结束之后,再将间隔除以2,在分成更多的子数组,再进行插入排序,以此类推,最后间隔为1,再进行一次插入排序也就完成了整个希尔排序。在一定程度上可以减少遍历的时间
在程序上的实现又和我们人的思维不太一样,电脑毕竟可以批处理,计算的快,如下图的实现:
思路:在一开始设置好gap之后,让指针指向第gap个元素,让其与它相隔gap的之前的所有的元素进行比较,小的元素就往前移,这样一轮下来,就相当于完成了它的一个子数组的一部分排序(一个子数组的gap的之前的元素进行了排序),假设是含有n个元素的数组,进行n-gap轮,就能将这一次的gap所分的子数组进行全部排序,接着继续将gap缩小,直到gap=1,就排序完成了

根据下面代码可知:**希尔排序的时间复杂度为→O(n^(1.3—2)) **

def shell_sort(alist):
    n = len(alist)
    gap = n // 2
    while gap > 0:
        for j in range(gap, n):
            i = j
            while i > 0:
                if alist[i] < alist[i - gap]:
                    alist[i], alist[i - gap] = alist[i - gap], alist[i]
                    i -= gap
                else:
                    break
        gap//=2

li = [1, 5, 6, 7, 3, 2, 55, 33]
shell_sort(li)
print(li)

输出:

[1, 2, 3, 5, 6, 7, 33, 55]

Process finished with exit code 0

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值