記事のディレクトリ
検索する
検索は、アイテムのコレクションから特定のアイテムを見つけるアルゴリズムプロセスです。アイテムが存在するかどうかのために、検索は通常、真または偽の答えです。検索のいくつかの一般的な方法:順次検索、バイナリ検索、バイナリツリー検索、ハッシュ検索。
二分探索
まず、テーブル内の要素が昇順で配置されていると仮定し、テーブルの中央位置にあるレコードのキーを検索キーと比較します。2つが等しい場合は検索が成功します。それ以外の場合は、中央を使用します。テーブルを1番目と2番目のサブテーブルに分割する位置レコード。中央の位置レコードのキーが検索キーより大きい場合は、前のサブテーブルがさらに検索されます。それ以外の場合は、後者のサブテーブルがさらに検索されます。条件を満たすレコードが見つかり検索が成功するまで、またはサブテーブルが存在しなくなるまで、この時点で検索が失敗するまで、上記のプロセスを繰り返します。
アルゴリズムの分析
// An highlighted block
'''递归实现,产生新的数组进行查找'''
def binary_search(alist, item):
n=len(alist)
if n>0:
midpoint = n//2
if alist[midpoint]==item:
return True
else:
# 调用binary_search实现递归,再次查找
if item<alist[midpoint]:
return binary_search(alist[:midpoint],item)
else:
return binary_search(alist[midpoint+1:],item)
testlist = [5,7,11,13,20,30,65]
print("递归实现")
print(binary_search(testlist, 3))
print(binary_search(testlist, 13))
'''非递归实现,在原本的数组中查找'''
def binary_search(alist, item):
first = 0
last = len(alist) - 1
while first <= last:
midpoint = (first + last) //2
#按重点值左右查找
if alist[midpoint] == item:
return True
elif item < alist[midpoint]:
last = midpoint - 1
else:
first = midpoint + 1
return False
testlist = [5,7,11,13,20,30,65]
print("非递归实现")
print(binary_search(testlist, 3))
print(binary_search(testlist, 13))
バイナリ検索は、バイナリ検索とも呼ばれます。その利点は、比較時間が短く、検索速度が速く、平均パフォーマンスが高いことです。欠点は、検索するテーブルが順序付きリストである必要があり、挿入と削除が難しいことです。したがって、二分探索法は、頻繁に変更されない頻繁に順序付けられたリストを検索するのに適しています。
時間の複雑さ
最適な時間計算量:O(1)
最悪の時間計算量:O(logn)
ツリーとツリーアルゴリズム
ツリー(英語:tree)は、抽象データ型(ADT)またはこの抽象データ型を実装するデータ構造であり、ツリー構造の性質を持つデータ収集をシミュレートするために使用されます。これは、階層コレクションを形成するn(n> = 1)個の有限ノードで構成されます。
機能:
各ノードには0個以上の子ノードがあります。
親ノードのないノードはルートノードと呼ばれます。
各非ルートノードには1つの親ノードしかありません。
ルートノードを除いて、各子ノードは複数の分離ノードに分割できます。サブツリー
樹木タイプ
順序付けられていないツリー
ツリー内のどのノードの子ノードにも順序関係はありません。この種のツリーは、順序付けされていないツリーと呼ばれ、フリーツリーとも呼ばれます。
注文したツリー
ツリー内の任意のノードの子ノード間には順序関係があります。この種のツリーは順序付きツリーと呼ばれます。
- 二分木:ノードごとに最大2つのサブツリーを持つ木は二分木と呼ばれます。
完全な二分木:二分木の場合、その深さがd(d> 1)であると仮定します。d層を除いて、他の層のノード数が最大になり、d層のすべてのノードが左から右に密に配置されています。このような二分木は完全二分木と呼ばれます。完全な二分木はすべて葉です下部にノードがある完全な二分木。
完全な二分木:葉ノードを除いて、各ノードには左右の子葉があり、葉ノードは最下位レベルにあります。
平衡二分木(AVLツリー):いずれかのノードの2つのサブツリー間の高さの差が1つ以下のバイナリツリー。
バイナリツリーの並べ替え(バイナリ検索ツリー(英語:バイナリ検索ツリー)、バイナリ検索ツリーとも呼ばれ、順序付けられたバイナリツリー);
2.ハフマンツリー(情報コーディングに使用):重み付きパスが最短のバイナリツリーはハフマンと呼ばれますツリーまたは最適な二分木;
3。Bツリー:読み取りおよび書き込み操作用に最適化された自己平衡型二分探索木。データを順番に保つことができ、3つ以上のサブツリーがあります。
二分木
二分木は、ノードごとに最大2つのサブツリーを持つツリー構造です。通常、サブツリーは「左サブツリー」および「右サブツリー」と呼ばれます。
二分木の特性(特性)
プロパティ1:二分木のi番目のレベルに最大2 ^(i-1)ノード(i> 0)があります
プロパティ2:深さkの二分木は最大2 ^ k-1ノード( k> 0)
プロパティ3:任意の二分木について、葉ノードの数がN0で、次数2のノードの総数がN2の場合、N0 = N2 + 1;
プロパティ4:完全な二分木の深さn個のノードはlog2(n + 1)である必要があります
プロパティ5:完全なバイナリツリーの場合、上から下、左から右に番号が付けられている場合、ノードにはi、左側の子番号は2i、右側の子番号は2iである必要があります。 2i +1である必要があります;その親番号はi / 2である必要があります(i = 1はルートです)
二分木のトラバーサル
ツリートラバーサルは、ツリーの重要な操作です。いわゆるトラバーサルとは、ツリー内のすべてのノードの情報へのアクセス、つまり、ツリー内の各ノードに1回だけアクセスすることを指します。この種のすべてのノードへのアクセスをトラバーサルと呼びます。次に、2つの重要なツリートラバーサルモードは、深さ優先トラバーサルと幅優先トラバーサルです。深さ優先は通常再帰を使用し、幅優先は通常キューを使用します。一般に、再帰的に実装できるアルゴリズムのほとんどは、スタックを使用して実装することもできます。
幅優先探索
ツリーのルートから始めて、ツリー全体のノードを左から右に上から下にトラバースします。
// An highlighted block
class Node(object):
"""节点类"""
def __init__(self, item):
self.elem = item
self.lchild = None #设为左边的孩子
self.rchild = None #设为右边的孩子
"""二叉树"""
class Tree(object):
def __init__(self):
self.root = None
"""为树添加节点"""
def add(self, item):
node = Node(item) #构建节点
#如果树是空的,则对根节点赋值
if self.root == None:
self.root = node
return
queue=[self.root]
while queue:
#弹出队列的第一个元素
cur_node = queue.pop(0)
#如果左边的孩子是否为空,为空,则进行赋值
#判断左边的孩子是否为空,不为空,则对下一个进行判断
if cur_node.lchild == None:
cur_node.lchild = node
return
else:
queue.append(cur_node.lchild)
# 如果右边的孩子是否为空,为空,则进行赋值
# 判断右边的孩子是否为空,不为空,则对下一个进行判断
if cur_node.rchild == None:
cur_node.rchild = node
return
else:
#如果左右子树都不为空,加入队列继续判断
queue.append(cur_node.rchild)
'''广度遍历'''
def breadth_travel(self):
if self.root is None:
return
queue = [self.root]
while queue:
cur_node=queue.pop(0)
print(cur_node.elem)
if cur_node.lchild is not None:
queue.append(cur_node.lchild)
if cur_node.rchild is not None:
queue.append(cur_node.rchild)
if __name__=="__main__":
tree=Tree()
tree.add(1)
tree.add(2)
tree.add(3)
tree.add(4)
tree.add(5)
tree.breadth_travel()
深さ優先探索
二分木の場合、深さ優先探索は、木の深さに沿って木のノードをトラバースし、木の枝を可能な限り深く探索することです。
次に、深度トラバーサルには3つの重要な方法があります。これらの3つの方法は、ツリーのノードにアクセスするためによく使用されます。これらの方法の違いは、各ノードにアクセスする順序にあります。これらの3種類のトラバーサルは、プレオーダー、インオーダー、およびポストオーダーと呼ばれます。
プレオーダートラバーサル
ルートノード->左サブツリー->右サブツリー
// An highlighted block
"""递归实现先序遍历"""
def preorder(self, root):
if root == None:
return
print(root.elem,end="\t")
self.preorder(root.lchild)
self.preorder(root.rchild)
インオーダートラバーサル
左のサブツリー->ルートノード->右のサブツリー
"""递归实现中序遍历"""
def inorder(self, root):
if root == None:
return
self.inorder(root.lchild)
print(root.elem,end="\t")
self.inorder(root.rchild)
注文後のトラバーサル
左のサブツリー->右のサブツリー->ルートノード
// An highlighted block
"""递归实现后续遍历"""
def postorder(self, root):
if root == None:
return
self.postorder(root.lchild)
self.postorder(root.rchild)
pprint(root.elem,end="\t")
二分木は、木を横断することによって決定されます
一次トラバーサル0137849256ルール:ルート左と右
、中次トラバーサル7381940526ルール:左ルート右