zoukankan      html  css  js  c++  java
  • 排序与搜索

    排序与搜索

    排序算法(英语:Sorting algorithm)是一种能将一串数据依照特定顺序进行排列的一种算法。

    排序算法的稳定性

    稳定性:稳定排序算法会让原本有相等键值的纪录维持相对次序。也就是如果一个排序算法是稳定的,当有两个相等键值的纪录R和S,且在原本的列表中R出现在S之前,在排序过的列表中R也将会是在S之前。

    冒泡排序

    冒泡排序(英语:Bubble Sort)是一种简单的排序算法。它重复地遍历要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来。遍历数列的工作是重复地进行直到没有再需要交换,也就是说该数列已经排序完成。这个算法的名字由来是因为越小的元素会经由交换慢慢“浮”到数列的顶端。

    冒泡排序算法的运作如下:

    • 比较相邻的元素。如果第一个比第二个大(升序),就交换他们两个。
    • 对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对。这步做完后,最后的元素会是最大的数。
    • 针对所有的元素重复以上的步骤,除了最后一个。
    • 持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。
    def bubble_sort(li):
        n = len(li)
        # 总共排序几趟 ,n - 1 目的是为了空间排序的次数
        for j in range(n-1):  # j = 0 1 2 3
            count = 0
            # 排序一趟,找到一个最大的数,排到最右边
            for i in range(n-1-j): # 排序的次数 越来越小
                # 比较相邻的两个数
    
                if li[i] > li[i + 1]:
                    li[i], li[i + 1] = li[i + 1], li[i]
                    count += 1
            if count == 0:
                break
    
    if __name__ == '__main__':
        li = [1,2,3,4,5]
        bubble_sort(li)
        print(li)
        # 最坏时间复杂度 O(n^2)
        # 最优时间复杂度 O(n)
        # 稳定性 稳定

    选择排序

    选择排序(Selection sort)是一种简单直观的排序算法。它的工作原理如下。首先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置,然后,再从剩余未排序元素中继续寻找最小(大)元素,然后放到已排序序列的末尾。以此类推,直到所有元素均排序完毕。

    def select_sort(li):
        n = len(li)
        # 让temp 从 0 ~ n-2 每次循环,选择一个最小的数,替换到j位置
        for j in range(n-1):
    
            # 把0位置的数据,跟后面所有的数进行比较
            # 比出来最小的数,放到0位置
            # 把0位置角标记录,跟后面所有的数进行比较
            temp = j
            for i in range(j + 1, n):
                if li[i] < li[temp]:
                    # 记录最小的数的角标
                    temp = i
            # for循环结束后,temp是最小的数的角标
            li[temp], li[j] = li[j], li[temp]
    
    
    if __name__ == '__main__':
        li = [3,3,5,2,1]
        select_sort(li)
        print(li)
        # 最坏时间复杂度:O(n^2)
        # 最优时间复杂度:O(n^2)
        # 稳定性:不稳定 [3,3,5,2,1]

    插入排序

    插入排序(英语:Insertion Sort)是一种简单直观的排序算法。它的工作原理是通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入。插入排序在实现上,在从后向前扫描过程中,需要反复把已排序元素逐步向后挪位,为最新元素提供插入空间。

    def insert_sort(li):
        n = len(li)
        for j in range(1,n):
            # 把1位置到n位置的数,依次进行插入排序
            # 一次插入,把前面的数据认为有序,把当前位置的数据插入到前面的有序序列中
            for i in range(j, 0 , -1):
                if li[i] < li[i - 1]:
                    li[i], li[i - 1] = li[i - 1], li[i]
                else:
                    break
    
    if __name__ == '__main__':
        li = [3,1,5,2,6]
        insert_sort(li)
        print(li)
        # 最坏时间复杂度:O(n^2)
        # 最优时间复杂度:O(n)
        # 稳定性:稳定

    快速排序

    快速排序(英语:Quicksort),又称划分交换排序(partition-exchange sort),通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。

    步骤为:

    1. 从数列中挑出一个元素,称为"基准"(pivot),
    2. 重新排序数列,所有元素比基准值小的摆放在基准前面,所有元素比基准值大的摆在基准的后面(相同的数可以到任一边)。在这个分区结束之后,该基准就处于数列的中间位置。这个称为分区(partition)操作。
    3. 递归地(recursive)把小于基准值元素的子数列和大于基准值元素的子数列排序。

    递归的最底部情形,是数列的大小是零或一,也就是永远都已经被排序好了。虽然一直递归下去,但是这个算法总会结束,因为在每次的迭代(iteration)中,它至少会把一个元素摆到它最后的位置去。

    快速排序的分析

    def quick_sort(alist, first, last):
        """快速排序"""
        if first >= last:
            return
        mid_value = alist[first]
        low = first
        high = last
        while low < high:
            # high 左移
            while low < high and alist[high] >= mid_value:
                high -= 1
            alist[low] = alist[high]
    
            while low <high and alist[low] < mid_value:
                low += 1
            alist[high] = alist[low]
        # 从循环退出时,low==high
        alist[low] = mid_value
    
        # 对low左边的列表执行快速排序
        quick_sort(alist, first, low-1)
    
        # 对low右边的列表排序
        quick_sort(alist, low+1, last)
    
    
    if __name__ == "__main__":
        li = [54, 26, 93, 17, 77, 31, 44, 55, 20]
        print(li)
        quick_sort(li, 0, len(li)-1)
        print(li)

     二叉树

    View Code

    二分查找 

    View Code

    队列 

    View Code

    双端队列

    View Code

    View Code

    单向链表 

    View Code

    双向链表

    View Code

    单向循环链表

    View Code
  • 相关阅读:
    LeetCode15 3Sum
    LeetCode10 Regular Expression Matching
    LeetCode20 Valid Parentheses
    LeetCode21 Merge Two Sorted Lists
    LeetCode13 Roman to Integer
    LeetCode12 Integer to Roman
    LeetCode11 Container With Most Water
    LeetCode19 Remove Nth Node From End of List
    LeetCode14 Longest Common Prefix
    LeetCode9 Palindrome Number
  • 原文地址:https://www.cnblogs.com/zhangyangcheng/p/8150208.html
Copyright © 2011-2022 走看看