時間複雜度和搜索算法

 

計算時間複雜度

1.通常狀況下,咱們須要考慮三種常見的情形
    1>最佳狀況運行時間是輸入最有利的狀況下算法的運行時間;
    2>最差情形運行時間是給定輸入規模的狀況下最長的運行時間;
    3>平均情形運行時間是在給定輸入規模的狀況下的平均運行時間。

漸進表示法

1.漸進表示法討論算法運行時間與輸入規模之間的關係;做爲一種對「特別大」的表示方法,漸進表示法,漸進表示法描述了輸入規模趨於無窮大時的算法複雜度;
2.漸進複雜度的規則描述:
    1>若是運行時間是一個多項式的和,那麼保留增加速度最快的項,去掉其餘各項;
    2>若是剩下的項是個乘積,那麼去掉全部的常數。
3.漸進表示法也稱爲「大O」表示法,大O表示法能夠給出一個函數漸進增加的上界。

重要時間複雜度

1.O(1)表示常數運行時間
    與輸入規模沒有無關
2.O(logn)表示對數運行時間
    增加速度至少是某個輸入的對數(二分查找法)
3.O(n)表示線性運行時間
    不少處理列表或其餘類型序列的程序具備線性複雜度,由於他們對序列中的每一個元素都進行常數(大於0)次處理
4.O(nlogn)表示對數線性運行時間
    它是兩個項的乘積,每一個項都依賴於輸入的規模(歸併排序)
5.O(n**K)表示多項式運行時間,K是常數
    最長見的是平方複雜度,也就是說算法複雜度按照輸入規模的平方增加
6.O(c**n)表示指數運行時間,這時常數c爲底數,複雜度爲c的n次方。
    所需的時間要隨規模的指數而增加

搜索算法

1.搜索算法就是在一個項目集合中找出一個或一組具備某種特色的項目;咱們將項目集合稱爲搜索空間
2.間接引用:要訪問目標元素時,先訪問另外一個元素,再經過包含在這個元素中的引用來訪問目標元素。咱們每次使用變量引用於變量綁定的對象時,便是這麼作的,而當咱們使用一個變量訪問列表並使用保存在列表中的引用訪問另外一個對象時,實際上進行了雙重間接引用。
3.二分查找
    **思路**:
        1>選擇一個能夠將列表L大體一分爲二的索引i;
        2>檢查是否有L[i] = e;
        3>若是不是,檢查L[i]大於仍是小於e;
        4>根據上一步的結果,肯定在L的左半部分仍是右半部分搜索e。
    **代碼:**
        def search(L, e):
            """假設L是列表,其中元素按升序排列。
            ascending order.
            若是e是L中的元素,則返回True,不然返回False"""

        def bSearch(L, e, low, high):
            #Decrements high – low
            if high == low:
                return L[low] == e
                mid = (low + high)//2
            if L[mid] == e:
                return True
            elif L[mid] > e:
                if low == mid: #nothing left to search
                    return False
                else:
                    return bSearch(L, e, low, mid - 1)
            else:
                return bSearch(L, e, mid + 1, high)
        if len(L) == 0:
            return False
        else:
            return bSearch(L, e, 0, len(L) - 1)

排序算法

1.選擇排序:維持一個循環不變式,他將列表分爲前綴部分(L[0:i])和後綴部分(L[i+1:len(L)]),前綴部分已經排好序,並且每一個元素都不大於後綴部分中的最小元素。
    **思路:**
        1>基礎情形:第一次迭代開始時,前綴集合是空的,也就是說,後綴集合是整個列表,所以,不變式成立
        2>概括步驟:在算法中的每一步,咱們都從後綴集合向前綴集合移動一個元素,移動的方式是將後綴集合中的最小元素添加到前綴集合的末尾
        3>結束:退出循環時,前綴集合包括了整個列表,後綴集合是空的,所以,整個列表按照升序排序。
    **代碼:**
        def selSort(L):
            """假設L是列表,其中的元素能夠用>進行比較。
                    compared using >.
                對L進行升序排列"""
            suffixStart = 0
            while suffixStart != len(L):
            #檢查後綴集合中的每一個元素
            for i in range(suffixStart, len(L)):
                if L[i] < L[suffixStart]:
                #交換元素位置
                L[suffixStart], L[i] = L[i], L[suffixStart]
            suffixStart += 1
2.歸併排序:是一種典型的分治算法,分治算法就是先找出初始問題的一些簡單實例的解,再將這些解組合起來做爲初始問題的解
    **思路:**
        1>若是列表的長度是0或1,那麼它已經排好序了;
        2>若是列表包含多於1個元素,就將其分爲兩個列表,並分別使用歸併排序法進行排序;
        3>合併結果。
    **代碼**
        def merge(left, right, compare):
            """假設left和right是兩個有序列表,compare定義了一種元素排序規則。
                返回一個新的有序列表(按照compare定義的順序),其中包含與
                (left+right)相同的元素。"""

        result = []
        i,j = 0, 0
        while i < len(left) and j < len(right):
            if compare(left[i], right[j]):
                result.append(left[i])
                i += 1
            else:
                result.append(right[j])
                j += 1
            while (i < len(left)):
                result.append(left[i])
                i += 1
            while (j < len(right)):
                result.append(right[j])
                j += 1
            return result

            def mergeSort(L, compare = lambda x, y: x < y):
                """假設L是列表,compare定義了L中元素的排序規則
                    on elements of L
                    返回一個新的具備L中相同元素的有序列表。"""
            if len(L) < 2:
                return L[:]
            else:
                middle = len(L)//2
                left = mergeSort(L[:middle], compare)
                right = mergeSort(L[middle:], compare)
                return merge(left, right, compare)
相關文章
相關標籤/搜索