データ構造 - ツリーの深さ優先トラバーサル(再帰的及び非再帰的、Python実装)

キュー、スタック、リンクリスト、あなたハンズオン練習はまだ私たちの目の前で?今日、私たちは木の一部に来て、ツリーはデータ構造で非常に重要な部分である、木の多くの、多くの用途があり、樹種があり、多くの、多くの、今日我々は、共通のツリーを作成する必要があります。将来のために一つの木の他の種類は、私はあなたを教えてくれる、私は〜ああ私の記事の注意を覚えています

まず、ツリーの形状は、このように似ています。

ツリー

これは、ツリーの最上位のルート上のポイントと呼ばれ、ツリーが唯一のルートノードを持つことができ、ノードは、以下の複数の子ノード、子ノード、我々はここで必要とされていないの番号を持つことができますが、呼び出された子ノードが存在しませんリーフノード。

さて、その後、私たちは木を作成し、実行して再びハンズオンほど良好ではない千回それを行うことがたくさんここに紹介のツリーの基本的な考え方、学びます:

ツリー

# 定义一个普通的树类
class Tree:
    def __init__(self, data):
        self.data = data
        self.children = []

    def get(self):
        return self.data
    
    def set(self):
        return self.data

    def addChild(self, child):
        self.children.append(child)

    def getChildren(self):
        return self.children

これは、私たちがクラスツリー、ツリーを定義し、子ノードを取得する、の三つの方法、すなわち、データ収集ノード、ノードのデータセットを追加した子ノードを追加するものです。

ここで、ツリーノードクラスのタイプは、実際には、そのようなノードの数は、ツリーを構成することができる、と我々は、ツリーのルートを表すために使用されます。

次は、ツリーをインスタンス化します。

# 初始化一个树
tree = Tree(0)
# 添加三个子节点
tree.addChild(Tree(1))
tree.addChild(Tree(2))
tree.addChild(Tree(3))
children = tree.getChildren()
# 每个子节点添加两个子节点
children[0].addChild(Tree(4))
children[0].addChild(Tree(5))
children[1].addChild(Tree(6))
children[1].addChild(Tree(7))
children[2].addChild(Tree(8))
children[2].addChild(Tree(9))

私たちは、おそらく次のようになり良い木をインスタンス化します。
ツリー

OK、我々はうまくツリーの例を持って、道再帰と非再帰的な幅優先横断しているのは、それをみましょう:

幅優先トラバーサル

幅優先トラバーサル、その1つのレベルのツリートラバーサルに左から右へ、上から下へ、です。

幅優先トラバーサル非再帰的な方法は、我々は先に説明したキューのタイプを使用し、そうできるようにする必要がある場合のキュークラスを定義します。

# 用以实现广度优先遍历
class Queue():
    def __init__(self):
        self.__list = list()

    def isEmpty(self):
        return self.__list == []

    def push(self, data):
        self.__list.append(data)
    
    def pop(self):
        if self.isEmpty():
            return False
        return self.__list.pop(0)

キューによって達成幅優先トラバーサル

限り、我々は、キューノードを使用すると、チームは、チームのノードの子ができましょうとき。

# 广度优先遍历
def breadthFirst(tree):
    queue = Queue()
    queue.push(tree)
    result = []
    while not queue.isEmpty():
        node = queue.pop()
        result.append(node.data)
        for c in node.getChildren():
            queue.push(c)
    return result

それを呼び出します。

print(breadthFirst(tree))

出力:[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

再帰幅優先トラバーサル

# 递归方式实现广度优先遍历
def breadthFirstByRecursion(gen, index=0, nextGen=[], result=[]):
    
    if type(gen) == Tree:
        gen = [gen]
    result.append(gen[index].data)
    
    children = gen[index].getChildren()
    
    nextGen += children
    if index == len(gen)-1:
        if nextGen == []:
            return
        else:
            gen = nextGen
            nextGen = []
            index = 0
    else:
        index += 1
    breadthFirstByRecursion(gen, index, nextGen,result)

    return result

それを呼び出します。

print(breadthFirstByRecursion(tree))

出力:[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

深さ優先探索

深さ優先トラバーサル、すなわち、上から下へ、左から右に、第一のサブノードトラバーサルノードの兄弟は、その後、ノードを横切ります。

深さ優先探索の方法、それを達成するための非再帰的に、我々は以前に導入されたスタック構造を使用する必要があるので、私たちは今、それをクラスのスタックを定義します。

# 用以实现深度优先遍历
class Stack():
    def __init__(self):
        self.__list = list()

    def isEmpty(self):
        return self.__list == []

    def push(self, data):
        self.__list.append(data)
    
    def pop(self):
        if self.isEmpty():
            return False
        return self.__list.pop()

深さ優先探索を使用したスタックの実装

深さ優先探索を実現し、私達はちょうど左から右に、このノードの子ノードをスタックにプッシュすることができたときにノードで開くことができます。

# 深度优先遍历
def depthFirst(tree):
    stack = Stack()
    stack.push(tree)
    result = []
    while not stack.isEmpty():
        node = stack.pop()
        result.append(node.data)
        children = node.getChildren()
        children = reversed(children)
        for c in children:
            stack.push(c)
    return result

それを呼び出します。

# 深度优先遍历
print(depthFirst(tree))

出力:[0, 1, 4, 5, 2, 6, 7, 3, 8, 9]

再帰深さ優先探索

# 递归方式实现深度优先遍历
def depthFirstByRecursion(tree, result=[]):
    result.append(tree.data)
    children = tree.getChildren()
    for c in children:
        depthFirstByRecursion(c, result)
    return result

それを呼び出します。

print(depthFirstByRecursion(tree))

出力:[0, 1, 4, 5, 2, 6, 7, 3, 8, 9]

さて、私たちはここに木を紹介します今日は、幅優先トラバーサル再帰的な実装のために、あなたはこれを行うには良い方法がありますか?私に伝えるためにメッセージを残してください。

おすすめ

転載: www.cnblogs.com/dongyangblog/p/11204612.html