Python__数据结构与算法——查找与排序
?
查找和排序是最基本的算法,在很多腳本中都會(huì)用到查找和排序。盡管 Python 提供的用于查找和排序的函數(shù)能夠滿足絕大多數(shù)需求,但還是有必要了解最基本的查找和排序算法,以便在有特殊需求的情況下,可以自己編寫查找、排序腳本。
一、查找
基本的查找方法有順序查找、二分查找和分塊查找等。其中,順序查找是最簡單的查找方法,就是按照數(shù)據(jù)排列的順序依次查找,直到找到所查找的數(shù)據(jù)為止(可查看數(shù)據(jù)表都未找到數(shù)據(jù))。
二分查找是首先對(duì)要進(jìn)行查找的數(shù)據(jù)進(jìn)行排序,有按大小順序排好的 9 個(gè)數(shù)字,如圖-1所示。如果要進(jìn)行查找數(shù)字 5,則首先與中間值 10 進(jìn)行比較,5 小于 10,于是對(duì)序列的前半部分 1~9 進(jìn)行查找。此時(shí),中間值為 5,恰好為要找的數(shù)字,查找結(jié)束。
分塊查找,是介于順序查找和二分查找之間的一種查找方法。使用分塊查找時(shí),首先對(duì)查找表建立一個(gè)索引表,然后再進(jìn)行分塊查找。建立索引表時(shí),首先對(duì)查找表進(jìn)行分塊,要求 "分塊有序",即塊內(nèi)關(guān)鍵字不一定有序,但分塊之間有大小順序。索引表是抽取各塊中的最大關(guān)鍵字及其起始位置構(gòu)成的,如圖-2 所示。
分塊查找分兩步進(jìn)行,首先查找索引表,因?yàn)樗饕硎怯行虻?#xff0c;查找索引表時(shí)可以使用二分查找法進(jìn)行。查找完索引表以后,就確定了要查找的數(shù)據(jù)所在的分塊,然后在該分塊中再進(jìn)行順序查找。
下面所示的 pyBinarySearch.py 腳本是對(duì)一個(gè)有序列表使用二分查找。
# -*- coding:UTF-8 -*- # file: pyBinarySearch.pydef BinarySearch(l, key): # 二分查找low = 0high = len(l) - 1i = 0while low <= high:i = i + 1mid = (high + low) // 2if l[mid] < key:low = mid + 1elif l[mid] > key:high = mid - 1else:print('use %d time(s)' % i)return midreturn -1if __name__ == '__main__':l = [1, 5, 6, 9, 10, 51, 62, 65, 70] # 構(gòu)造列表print(BinarySearch(l, 5)) # 在列表中查找print(BinarySearch(l, 10))print(BinarySearch(l, 65))print(BinarySearch(l, 70))運(yùn)行腳本輸出結(jié)果如下:
二、排序
對(duì)于查找來說,排序要復(fù)雜得多,排序的方法也較多,常用的排序方法有冒泡法排序、希爾排序、二叉樹排序和快速排序等,其中,二叉樹排序是比較有意思的一種排序方法,而且也便于操作。二叉樹排序的過程主要是二叉樹的建立和遍歷的過程。例如,有一組數(shù)據(jù) "3,5,7,20,43,2,15,30",則二叉樹的建立過程如下。
- Step1:首先將第一個(gè)數(shù)據(jù) 3 放入根節(jié)點(diǎn)。
- Step2:將數(shù)據(jù) 5 與根節(jié)點(diǎn)中的數(shù)據(jù) 3 比較,由于 5 大于 3,因此應(yīng)將 5 放入 3 的右子樹中。
- Step3:將數(shù)據(jù) 7 與根節(jié)點(diǎn)中的數(shù)據(jù) 3 比較,由于 7 大于 3,因此應(yīng)將 5 放入 3 的右子樹中,由于 3 已經(jīng)有右兒子 5,所以將 7 與 5 進(jìn)行比較,因?yàn)?7 大于 5,所以應(yīng)將 7 放入 5 的右子樹中。
- Step4:將數(shù)據(jù) 20 與根節(jié)點(diǎn)中的數(shù)據(jù) 3 比較,由于 20 大于 3,因此應(yīng)將 20 放入 3 的右子樹中,重復(fù)比較,最終將 20 放入 7 的右子樹中。
- Step5:將數(shù)據(jù) 43 與樹中的節(jié)點(diǎn)值進(jìn)行比較,最終將其放入 20 的右子樹中。
- Step6:將數(shù)據(jù) 2 與根節(jié)點(diǎn) 3 進(jìn)行比較,由于 2 小于 3,因此應(yīng)將 2 放入 3 的左子樹。
- Step7:同樣的對(duì)數(shù)據(jù) 15 和 30 進(jìn)行處理,最終形成如圖-3 所示的樹。
當(dāng)樹創(chuàng)建好后,對(duì)數(shù)進(jìn)行中序遍歷,得到的遍歷結(jié)果就是對(duì)數(shù)據(jù)從小到大排序。如果要從大到小進(jìn)行排序則可以先從右子樹開始進(jìn)行中序遍歷。
下面所示的 pySort.py 腳本是采用二叉樹排序的方式對(duì)數(shù)據(jù)進(jìn)行排序。
# -*- coding:UTF-8 -*- # file: pySort.pyclass BTree: # 二叉樹節(jié)點(diǎn)def __init__(self, value): # 初始化函數(shù)self.left = None # 左兒子self.data = value # 節(jié)點(diǎn)值self.right = None # 右兒子def insertLeft(self, value): # 向左子樹插入節(jié)點(diǎn)self.left = BTree(value)return self.leftdef insertRight(self, value): # 向右子樹插入節(jié)點(diǎn)self.right = BTree(value)return self.rightdef show(self): # 輸出節(jié)點(diǎn)數(shù)據(jù)print(self.data)def inorder(node): # 中序遍歷if node.data:if node.left:inorder(node.left)node.show()if node.right:inorder(node.right)def rinorder(node): # 中序遍歷if node.data:if node.right:rinorder(node.right)node.show()if node.left:rinorder(node.left)def insert(node, value): # 中序遍歷,先遍歷右子樹if value > node.data:if node.right:insert(node.right, value)else:node.insertRight(value)else:if node.left:insert(node.left, value)else:node.insertLeft(value)if __name__ == '__main__':l = [3, 5, 7, 20, 43, 2, 15, 30]Root = BTree(l[0]) # 根節(jié)點(diǎn)node = Rootfor i in range(1,len(l)):insert(Root, l[i])print('**************************')print(' 從小到大')print('**************************')inorder(Root)print('**************************')print(' 從大到小')print('**************************')rinorder(Root)運(yùn)行 pySort.py 腳本后,輸出如下所示的排序結(jié)果:
總結(jié)
以上是生活随笔為你收集整理的Python__数据结构与算法——查找与排序的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Python__数据结构与算法——图
- 下一篇: websocket python爬虫_p