数据结构之排序

Posted 小小菜_v

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了数据结构之排序相关的知识,希望对你有一定的参考价值。

冒泡排序(时间复杂度:O(n^2))

1、比较两个相邻的元素,如果前一个大于后一个则交换位置;
2、对后面的元素都做第一步的操作,从首部开始到尾部结束,最终最大的元素将会排在最后一位;
3、循环重复上面一,二步操作,列表长度减一(不包含最后的一位元素,因为已是最大,无需排序)
4、直到没有数字比较,循环结束

方式一

def bubble_sort(lis):
    """
    冒泡排序
    :param lis:
    :return:
    """
    for i in range(len(lis)-1):
	    for j in range(len(lis)-i-1):
	        if lis[j] > lis[j+1]:
	            lis[j], lis[j+1] = lis[j+1], lis[j]
	    print(lis)


lis = [3, 1, 2, 4, 9, 4, 10, 7]
bubble_sort(lis)

输出

C:\\Users\\MI\\AppData\\Local\\Programs\\Python\\Python310\\python.exe D:/python/bubble_sort.py
[1, 2, 3, 4, 4, 9, 7, 10]
[1, 2, 3, 4, 4, 7, 9, 10]
[1, 2, 3, 4, 4, 7, 9, 10]
[1, 2, 3, 4, 4, 7, 9, 10]
[1, 2, 3, 4, 4, 7, 9, 10]
[1, 2, 3, 4, 4, 7, 9, 10]
[1, 2, 3, 4, 4, 7, 9, 10]

从输出结果可以看出,第二趟就排序好了,但是后面还是循环了5次,我们可以进行优化一下

def bubble_sort(lis):
    """
    冒泡排序
    :param lis:
    :return:
    """
    for i in range(len(lis)-1):
        flag = False
        for j in range(len(lis)-i-1):
            if lis[j] > lis[j+1]:
                lis[j], lis[j+1] = lis[j+1], lis[j]
                flag = True
        if not flag:
            break
        print(lis)


lis = [3, 1, 2, 4, 9, 4, 10, 7]
bubble_sort_v2(lis)

输出

C:\\Users\\MI\\AppData\\Local\\Programs\\Python\\Python310\\python.exe D:/python/bubble_sort.py
[1, 2, 3, 4, 4, 9, 7, 10]
[1, 2, 3, 4, 4, 7, 9, 10]

当加一个标志,判断没有进行交换一次,那么就可以结束循环

选择排序(时间复杂度:O(n^2))

1、首先选择第一个元素的下标记录下来min_loc ;
2、从第二个元素开始,进行循环遍历,将取出来的元素和第一步选择的元素比较,若小于它,交换他们的下标,继续循环,直到找到最小的那个元素
循环结束,判断min_loc 是否和第一步记录下来的值相等,不等,则交换对应的元素值

def select_sort(lis):
    """
    选择排序
    :param lis:
    :return:
    """
    for i in range(len(lis)-1): # 第一次循环元素下标
        min_loc = i
        for j in range(i+1, len(lis)): # 第二个元素下标
            if lis[min_loc] > lis[j]: # 找到比min_loc所在位置小的元素
                min_loc = j  # min_loc重新赋值j
        if min_loc != i: #比较min_loc ,不同则交换元素值
            lis[min_loc], lis[i] = lis[i], lis[min_loc]
        print(lis)


lis = [3, 1, 2, 4, 9, 4, 2, 7]
print(lis)
select_sort(lis)

输出

C:\\Users\\MI\\AppData\\Local\\Programs\\Python\\Python310\\python.exe D:/python/select_sort.py
[3, 1, 2, 4, 9, 4, 2, 7]
[1, 3, 2, 4, 9, 4, 2, 7]
[1, 2, 3, 4, 9, 4, 2, 7]
[1, 2, 2, 4, 9, 4, 3, 7]
[1, 2, 2, 3, 9, 4, 4, 7]
[1, 2, 2, 3, 4, 9, 4, 7]
[1, 2, 2, 3, 4, 4, 9, 7]
[1, 2, 2, 3, 4, 4, 7, 9]

插入排序(时间复杂度:O(n^2))

插入排序相当于摸扑克牌,摸到下张牌与手中的牌进行对比,然后插入到合适的位置
1、手中已存在第一张牌,从第二张开始遍历
2、第二张和第一张比较,小于的话,需要交换位置插入到第一张前面
3、继续循环

def insert_sort(lis):
    """
    插入排序
    :param lis:
    :return:
    """
    for i in range(1, len(lis)): #i从第二个元素开始
        temp = lis[i] # 记录元素值
        j = i - 1 # 手中最右边的牌的下标

        while j >= 0 and lis[j] > temp:
            lis[j+1] = lis[j]
            j = j - 1
        lis[j + 1] = temp
    	print(lis)

lis = [3, 1, 2, 4, 9, 4, 2, 7]
insert_sort(lis)

输出

C:\\Users\\MI\\AppData\\Local\\Programs\\Python\\Python310\\python.exe D:/python/insert_sort.py
[3, 1, 2, 4, 9, 4, 2, 7]
[1, 3, 2, 4, 9, 4, 2, 7]
[1, 2, 3, 4, 9, 4, 2, 7]
[1, 2, 3, 4, 9, 4, 2, 7]
[1, 2, 3, 4, 9, 4, 2, 7]
[1, 2, 3, 4, 4, 9, 2, 7]
[1, 2, 2, 3, 4, 4, 9, 7]
[1, 2, 2, 3, 4, 4, 7, 9]

快速排序(时间复杂度(一般):O(nlogN))

1、取第一个元素temp,使temp归位到它应该在的位置,归位后,列表分为两部分,左边比temp小,右边比temp大;
递归完成排序

def partition(lis, left, right):
    temp = lis[left] # 第一个元素
    while left < right:
        while left < right and lis[right] >= temp:
            right -= 1
        lis[left] = lis[right]
        while left < right and lis[left] <= temp:
            left += 1
        lis[right] = lis[left]
    lis[left] = temp
    print(lis)
    return left


def quick_sorrt(lis, left, right):
    """
    快排
    :param lis:
    :param left:
    :param right:
    :return:
    """
    if left < right: # 两个指针,left为首部,right为尾部
        mid = partition(lis, left, right) # 获取元素temp归位后的下标
        quick_sorrt(lis, left, mid-1) # 递归列表左部分
        quick_sorrt(lis, mid+1, right) # 递归列表右部分


lis = [3, 1, 2, 4, 9, 4, 2, 7]
print(lis)
quick_sorrt(lis, 0, len(lis)-1)

输出

C:\\Users\\MI\\AppData\\Local\\Programs\\Python\\Python310\\python.exe D:/python/quick_sort.py
[3, 1, 2, 4, 9, 4, 2, 7]
[2, 1, 2, 3, 9, 4, 4, 7]
[1, 2, 2, 3, 9, 4, 4, 7]
[1, 2, 2, 3, 7, 4, 4, 9]
[1, 2, 2, 3, 4, 4, 7, 9]
[1, 2, 2, 3, 4, 4, 7, 9]

最坏情况:
1、递归的最大深度默认是1000,可以通过sys.setrecursionlimit(1005)修改;
2、当列表是逆序的情况下,每次递归就没有折半了(第一个temp可以随机选择一个)

以上是关于数据结构之排序的主要内容,如果未能解决你的问题,请参考以下文章

数据结构之排序

计算机网络之数据链路层

数据链路层

急!!IP数据报必须考虑最大传送单元MTU,这是指哪一层的最大传送单元?包括不包括首部或尾部等开销在内?

队列排序,先进先出

HAProxy修改报文首部