• 算法--排序


    #堆排
    def
    sift(li, low, high): ''' :param li:树 :param low: 树的根节点 :param high: 树的最后一个节点 :return:向下调整树 ''' tmp = li[low] # 去除树根作为临时变量 i = low # i指向空位 j = 2 * i + 1 # 第一次 j指向根节点的左孩子 while j <= high: # 循环继续的条件:j不越界;This the second end condition:j越界 # 1.比较左右子节点 if j + 1 <= high and li[j] < li[j + 1]: # 右节点存在,才进行左右比较 j += 1 # 将j指向j+1 if li[j] > tmp: # 调整位置 li[i] = li[j] # 空位的元素填成j下标的元素,所谓的调整 i = j # 向下调整 j = 2 * j + 1 # 从当前j节点找左孩子 else: break # j位置的元素>tmp 停止循环,This the first end condition li[i] = tmp # 结束循环,空位填充tmp #堆排 def heak_sort(li): n = len(li) # 1.构造堆 for low in range((n - 2) // 2, -1, -1): # 根据子节点找父节点i-->(i-1)//2 sift(li, low, n - 1) print(li) # 2.挨个出数 for high in range(n - 1, -1, -1): li[0], li[high] = li[high], li[0] sift(li, 0, high - 1) # 排除堆中的最后一个元素 li = [8, 1, 2, 6, 3, 7] heak_sort(li) print(li) # [1, 2, 3, 6, 7, 8]
    #冒泡排序 时间复杂度O(n*n)
    def bubble_sort(li):
        for i in range(len(li)):  # 表示躺数n躺
            flag = False
            for j in range(len(li) - 1 - i):  # 表示第n躺无序区的范围  0--n-i-1
                if li[j] > li[j + 1]:
                    li[j], li[j + 1] = li[j + 1], li[j]
                    flag = True
            if not flag:  # 表示无序区已经有序
                break
        return li
    # 选择排序
    '''思路:选择一个最小的val,和无序区的第一个元素进行,交换.时间复杂度O(n*n)'''
    def select_sort(li):
        for i in range(len(li)):
            min_pos = i
            for j in range(i + 1, len(li)):
                if li[j] < li[min_pos]:
                    min_pos = j  # 更新最小值的下标
            li[i], li[min_pos] = li[min_pos], li[i]
        return li
    # 插入排序
    '''思路:选择一个数,和有序区的元素进行比较,如果小于有序区的元素,就将每一个元素向后挪(1.比较的下标<0;2.比较的数>选择的数),依次比较最后插入位置'''
    
    
    def insert_sort(li):
        for i in range(1, len(li)):  # 无序区的范围
            tmp = li[i]  # 默认取无序区的第一个元素和前面的每个元素进行比较
            j = i - 1  # 有序区的最后一个元素下标
            while j >= 0 and li[j] > tmp:  # ***必须是j>=0 and li[j]>tmp  否则li[-1]会error
                li[j + 1] = li[j]  # 向后挪
                j -= 1  # 向前找一个
            li[j + 1] = tmp  # 找到符合条件的下标j,后面一个空位即tmp的位置
        return li
    # 快速排序
    def quick_sort(li, left, right):
        '''nlogn'''
        if left < right:
            # 归为元素下标
            mid = partition(li, left, right)  # 归位
            quick_sort(li, left, mid - 1)  # 排 mid 左边的元素
            quick_sort(li, mid + 1, right)  # 排mid右边元素
        return li
    
    def partition(li, left, right):
        '''O(n)'''
        tmp = li[left]
        while left < right:  # 排序区至少有2个元素
            while left < right and li[right] > tmp:  # 从右边往左走,
                # if left == right:
                #     break
                right -= 1
            li[left] = li[right]  # 丢到左边
            while left < right and li[left] < tmp:  # left=3 越界 此时li[2]=li[3]
                # if left == right:
                #     break
                left += 1  # 加等完事儿后注意越界问题,left!!!
            li[right] = li[left]  # 丢到右边 越界导致问题----
    
        # 退出循环left == right ==mid
        li[left] = tmp  # 丢到右边 越界导致问题---- li[3]=tmp 导致【1,2,4,3,5】
        return left
    
    
    print(quick_sort([2,1,4,3,5],0,4))
    # 归并排序.:先分解在merge
    # 归并:时间复杂度O(n);空间复杂度O(n)  条件:一个列表中前后部分是有序的的[2,5,7,8,9,1,3,4,6,]
    def merge(li, low, mid, high):
        """
        思路:分别比较两段列表的每个元素的位置,如果谁小,谁添加进li_tmp;最后两边的列表会剩下,依次循环append即可
        :param li:排序的列表
        :param low: 开始的位置
        :param mid: 有序的分段的位置
        :param high: 结尾的位置
        :return:
        """
        li_tmp = []
        i = low
        j = mid + 1
        while i <= mid and j <= high:  # 考虑 = 的情况,最后j+1后 j=8;所有必须<=防止少
            if li[i] < li[j]:
                li_tmp.append(li[i])
                i += 1
            if li[j] < li[i]:
                li_tmp.append(li[j])
                j += 1
        # 剩下的元素
        while i <= mid:
            li_tmp.append(li[i])
            i += 1
        while j <= high:
            li_tmp.append(li[j])
            j += 1
        li[low:high + 1] = li_tmp
        return li
    
    
    # 归并排序O(nlog(n))
    def merge_sort(li, low, high):
        if low < high:
            mid = (low + high) // 2
            # print(li[low: mid + 1], li[mid + 1: high])
            # 分解左边
            merge_sort(li, low, mid)
            # 分解右边
            merge_sort(li, mid + 1, high)
            # print(li[low: mid + 1], li[mid + 1: high])
            # 归并
            merge(li, low, mid, high)
            print(li[low: mid + 1], li[mid + 1: high])
    
    
    li = [2, 5, 7, 8, 9, 1, 3, 4, 6]
    merge_sort(li, 0, 8)
    print(li)
  • 相关阅读:
    linux 安装 tomcat
    IE条件注释
    了解常见的开源协议(BSD, GPL, LGPL,MIT)
    Ueditor 1.4.3 单独调用上传图片,或文件功能
    javascript代码规范 [转]
    html5 拖曳功能的实现[转]
    几种常用的正则表达式[转]
    MYSQL基础03(日期函数)
    MYSQL基础02(查询)
    OpenCV(7)-图像直方图
  • 原文地址:https://www.cnblogs.com/liuer-mihou/p/12659785.html
Copyright © 2020-2023  润新知