查找和排序

查找:

  • 順序查找
  • 二分查找(折半查找)
  • 二叉排序樹查找
  • 哈希查找,時間復雜度O(1)
  • Fibonacci查找,時間復雜度O(logN)
  • 分塊查找槐瑞,時間復雜度O(logN+N/m)

排序:

  • 冒泡排序
  • 快速排序
  • 歸并排序
  • 插入排序
  • 選擇排序

查找:


順序查找嫌拣,時間復雜度O(N)

nums = [4,7,12,20,36,48,50,77,90]
n = 36
for i in nums:
    if(i == n):
        print(i)
        break
#輸出36

折半查找(其實就是二分查找)時間復雜度O(logN)

#二分查找,給定一個數字n,給定一個有序列表孝宗,找到數字n的下標,否則返回-1
def searchNum(n,list):
    low=0
    high=(len(list))

    while low<=high:
        mid = (low + high)//2
        if n>list[mid]:
            low=mid+1
        elif n<list[mid]:
            high=mid-1
        else:
            return mid
    return -1

list=[1,4,6,9,12,45,78,900,1212];
mid=searchNum(45,list)
print(mid)

二叉排序樹的查找

# 二叉樹查找 Python實現
class BSTNode:
    """
    定義一個二叉樹節(jié)點類耕肩。
    以討論算法為主因妇,忽略了一些諸如對數據類型進行判斷的問題。
    """
    def __init__(self, data, left=None, right=None):
        """
        初始化
        :param data: 節(jié)點儲存的數據
        :param left: 節(jié)點左子樹
        :param right: 節(jié)點右子樹
        """
        self.data = data
        self.left = left
        self.right = right


class BinarySortTree:
    """
    基于BSTNode類的二叉查找樹猿诸。維護一個根節(jié)點的指針婚被。
    """
    def __init__(self):
        self._root = None

    def is_empty(self):
        return self._root is None

    def search(self, key):
        """
        關鍵碼檢索
        :param key: 關鍵碼
        :return: 查詢節(jié)點或None
        """
        bt = self._root
        while bt:
            entry = bt.data
            if key < entry:
                bt = bt.left
            elif key > entry:
                bt = bt.right
            else:
                return entry
        return None

    def insert(self, key):
        """
        插入操作
        :param key:關鍵碼
        :return: 布爾值
        """
        bt = self._root
        if not bt:
            self._root = BSTNode(key)
            return
        while True:
            entry = bt.data
            if key < entry:
                if bt.left is None:
                    bt.left = BSTNode(key)
                    return
                bt = bt.left
            elif key > entry:
                if bt.right is None:
                    bt.right = BSTNode(key)
                    return
                bt = bt.right
            else:
                bt.data = key
                return

    def delete(self, key):
        """
        二叉查找樹最復雜的方法
        :param key: 關鍵碼
        :return: 布爾值
        """
        p, q = None, self._root     # 維持p為q的父節(jié)點,用于后面的鏈接操作
        if not q:
            print("空樹梳虽!")
            return
        while q and q.data != key:
            p = q
            if key < q.data:
                q = q.left
            else:
                q = q.right
            if not q:               # 當樹中沒有關鍵碼key時址芯,結束退出。
                return
        # 上面已將找到了要刪除的節(jié)點窜觉,用q引用谷炸。而p則是q的父節(jié)點或者None(q為根節(jié)點時)。
        if not q.left:
            if p is None:
                self._root = q.right
            elif q is p.left:
                p.left = q.right
            else:
                p.right = q.right
            return
        # 查找節(jié)點q的左子樹的最右節(jié)點禀挫,將q的右子樹鏈接為該節(jié)點的右子樹
        # 該方法可能會增大樹的深度淑廊,效率并不算高√嘏兀可以設計其它的方法季惩。
        r = q.left
        while r.right:
            r = r.right
        r.right = q.right
        if p is None:
            self._root = q.left
        elif p.left is q:
            p.left = q.left
        else:
            p.right = q.left

    def __iter__(self):
        """
        實現二叉樹的中序遍歷算法,
        展示我們創(chuàng)建的二叉查找樹.
        直接使用python內置的列表作為一個棧。
        :return: data
        """
        stack = []
        node = self._root
        while node or stack:
            while node:
                stack.append(node)
                node = node.left
            node = stack.pop()
            yield node.data
            node = node.right


if __name__ == '__main__':
    lis = [62, 58, 88, 48, 73, 99, 35, 51, 93, 29, 37, 49, 56, 36, 50]
    bs_tree = BinarySortTree()
    for i in range(len(lis)):
        bs_tree.insert(lis[i])
    # bs_tree.insert(100)
    bs_tree.delete(58)
    for i in bs_tree:
        print(i, end=" ")
    # print("\n", bs_tree.search(4))

哈希查找腻格,時間復雜度O(1)
分塊查找画拾,時間復雜度O(logN+N/m)
將列表分塊,找出最大值
先找最大值再順序查找

Fibonacci查找菜职,時間復雜度O(logN)

MAXSIZE = 20
#構建一個febonacci列表
def fibonacci():  # 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89
    f = [0] * MAXSIZE
    f[0] = 1
    f[1] = 1
    for i in range(2, MAXSIZE):
        f[i] = f[i-1] + f[i-2]
    return f
#搜索
def fibonacciSearch(array, value):
    low, mid, high = 0, 0, len(array)-1
    k = 0
    f = fibonacci()
#找到比給定數組大小的最小菲波那切數
    while len(array) > f[k]-1:
        k += 1
#將數組的長度補到fk-1的大大小青抛,數值為原列表最后的數值
    temp = array + [array[-1] * (f[k]-1-len(array))]
    while low <= high:
        mid = low + f[k-1] - 1
        if temp[mid] > value:
            high = mid - 1
            k = k - 1
        elif temp[mid] < value:
            low = mid + 1
            k = k - 2
        else:
            if mid <= high: # 如果在high位前,則返回mid位置酬核,否則返回high位置
                return mid
            else:
                return high
    return -1

if __name__ == '__main__':
    a = [1, 3, 5, 6, 7, 88]
    print(fibonacciSearch(a, 2))

差值查找蜜另,時間復雜度O(log(logN))
通過類比,我們可以將二分查找的點改進為如下:

mid=low+(high-low)*(key-a[low])/(a[high]-a[low])//(1/2)
換為(key-a[low])/(a[high]-a[low])

也就是將上述的比例參數1/2改進為自適應的嫡意,根據關鍵字在整個有序表中所處的位置举瑰,讓mid值的變化更靠近關鍵字key,這樣也就間接地減少了比較次數蔬螟。

排序
插入排序

#插入排序
# python
def insert_sort(data,dataSorted):
    if len(data)<1:
        return dataSorted
    temp=data.pop(0)
    if len(dataSorted)<1:
        dataSorted.append(temp)
        return insert_sort(data,dataSorted)
    i=0
    while  temp<dataSorted[i]:
        if i == len(dataSorted) - 1:
            break
        i+=1
    dataSorted.insert(i,temp)
    print(dataSorted)
    return insert_sort(data,dataSorted)
array=[1,3,7,4,3,2,6,8,4,2]
print(insert_sort(array,[]))

冒泡排序

def bubbleSort(arr):
    n = len(arr)
 
    # 遍歷所有數組元素
    for i in range(n):
 
        # Last i elements are already in place
        for j in range(0, n-i-1):
 
            if arr[j] > arr[j+1] :
                arr[j], arr[j+1] = arr[j+1], arr[j]
 
arr = [64, 34, 25, 12, 22, 11, 90]
 
bubbleSort(arr)
 
print ("排序后的數組:")
for i in range(len(arr)):
    print ("%d" %arr[i]),

快速排序

#快速排序
def sortQuckily(array):
    if len(array)<2:
        return array
    else:
        axis=array[0]
        less=[i for i in array[1:] if i<axis]
        greater=[i for i in array[1:] if i>axis]
    return sortQuckily(less)+[axis]+sortQuckily(greater)
kinoList=[1,4,6,3,98,4,33,67,1,4,0,6,3,78]
print(sortQuckily(kinoList))

我個人覺得這是快排最漂亮的代碼了

歸并排序

#先實現拆分
def cut(array):
    if len(array)<=1:
        print(array)
        return array
    mid=len(array)//2
    print(mid)

    left=cut(array[0:mid])
    right=cut(array[mid:len(array)])
    return  megret(left,right)
def megret(left,right):
    result=[]
    i,j=0,0
    while len(left)>i and len(right)>j:
        if left[i]>right[j]:
            result.append(right[j])
            j+=1
        else:
            result.append(left[i])
            i+=1
    result.extend(left[i:])
    result.extend(right[j:])
    return  result
array=[3,64,2]
print(cut(array))

選擇排序

#選擇排序
def chooseSort(listKino):
    smallest=listKino[0]
    index=0

    for i in range(1,len(listKino)):
        if(listKino[i]<smallest):
            smallest=listKino[i]
            index=i
    temp=listKino[index]
    del listKino[index]
    return temp

listKino=[1,3,9456,445,5,7,2,23232,34343,45,67,45454,4,12,89,112,778,3,2323,7845,9001,12121,90901]
listNew=[]
for i in range(len(listKino)):
    listNew.append(chooseSort(listKino))
print(listNew)

屏幕快照 2019-09-18 下午1.40.09.png
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
  • 序言:七十年代末此迅,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌耸序,老刑警劉巖忍些,帶你破解...
    沈念sama閱讀 216,324評論 6 498
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現場離奇詭異坎怪,居然都是意外死亡罢坝,警方通過查閱死者的電腦和手機,發(fā)現死者居然都...
    沈念sama閱讀 92,356評論 3 392
  • 文/潘曉璐 我一進店門搅窿,熙熙樓的掌柜王于貴愁眉苦臉地迎上來炸客,“玉大人,你說我怎么就攤上這事戈钢。” “怎么了是尔?”我有些...
    開封第一講書人閱讀 162,328評論 0 353
  • 文/不壞的土叔 我叫張陵殉了,是天一觀的道長。 經常有香客問我拟枚,道長薪铜,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,147評論 1 292
  • 正文 為了忘掉前任恩溅,我火速辦了婚禮隔箍,結果婚禮上,老公的妹妹穿的比我還像新娘脚乡。我一直安慰自己蜒滩,他們只是感情好,可當我...
    茶點故事閱讀 67,160評論 6 388
  • 文/花漫 我一把揭開白布奶稠。 她就那樣靜靜地躺著俯艰,像睡著了一般。 火紅的嫁衣襯著肌膚如雪锌订。 梳的紋絲不亂的頭發(fā)上竹握,一...
    開封第一講書人閱讀 51,115評論 1 296
  • 那天,我揣著相機與錄音辆飘,去河邊找鬼啦辐。 笑死,一個胖子當著我的面吹牛蜈项,可吹牛的內容都是我干的芹关。 我是一名探鬼主播,決...
    沈念sama閱讀 40,025評論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼紧卒,長吁一口氣:“原來是場噩夢啊……” “哼充边!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 38,867評論 0 274
  • 序言:老撾萬榮一對情侶失蹤浇冰,失蹤者是張志新(化名)和其女友劉穎贬媒,沒想到半個月后,有當地人在樹林里發(fā)現了一具尸體肘习,經...
    沈念sama閱讀 45,307評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡际乘,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,528評論 2 332
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現自己被綠了漂佩。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片脖含。...
    茶點故事閱讀 39,688評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖投蝉,靈堂內的尸體忽然破棺而出养葵,到底是詐尸還是另有隱情,我是刑警寧澤瘩缆,帶...
    沈念sama閱讀 35,409評論 5 343
  • 正文 年R本政府宣布关拒,位于F島的核電站,受9級特大地震影響庸娱,放射性物質發(fā)生泄漏着绊。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,001評論 3 325
  • 文/蒙蒙 一熟尉、第九天 我趴在偏房一處隱蔽的房頂上張望归露。 院中可真熱鬧,春花似錦斤儿、人聲如沸剧包。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,657評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽玄捕。三九已至,卻和暖如春棚放,著一層夾襖步出監(jiān)牢的瞬間枚粘,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,811評論 1 268
  • 我被黑心中介騙來泰國打工飘蚯, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留馍迄,地道東北人。 一個月前我還...
    沈念sama閱讀 47,685評論 2 368
  • 正文 我出身青樓局骤,卻偏偏與公主長得像攀圈,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子峦甩,可洞房花燭夜當晚...
    茶點故事閱讀 44,573評論 2 353

推薦閱讀更多精彩內容

  • 查找和排序都是程序設計中經常用到的算法赘来。查找相對而言較為簡單现喳,不外乎順序查找、二分查找犬辰、哈希表查找和二叉排序樹查找...
    eagleRock閱讀 5,579評論 0 14
  • 一些概念 數據結構就是研究數據的邏輯結構和物理結構以及它們之間相互關系嗦篱,并對這種結構定義相應的運算,而且確保經過這...
    Winterfell_Z閱讀 5,774評論 0 13
  • 首先總結以下Java和C幌缝、C++中的一般控制臺輸入方式灸促,方便以后的編程題: java鍵盤輸入 java讀文件(會自...
    androidjp閱讀 2,290評論 0 16
  • 概述 排序有內部排序和外部排序,內部排序是數據記錄在內存中進行排序涵卵,而外部排序是因排序的數據很大浴栽,一次不能容納全部...
    蟻前閱讀 5,183評論 0 52
  • 1.插入排序—直接插入排序(Straight Insertion Sort) 基本思想: 將一個記錄插入到已排序好...
    依依玖玥閱讀 1,253評論 0 2