深度优先遍历多叉树结构,输出叶子路径

树结构的深度优先遍历是应用中常见的问题

在实际项目中,多叉树出现的比较普遍,常用来存储类似字典词条的路径信息。

多叉树对于在一个序列中找到前缀匹配的所有路径是可行的选择,例如找到一段文字中所有前缀匹配的词条(中国人民解放军为例,有中,中国,中国人,中国人民,中国人民解放军等匹配词条)。

构造一棵包含所有中文词条的字典树,可以通过深度优先遍历快速解析出这些前缀匹配的词条,树的每一个节点都是一个汉字,尔从根节点出发的路径是存储的中文词条。

以下的代码是一段示例,它的遍历会输出所有的叶子节点。

树结构是一个名为Tree的类型模板,其中存储了TreeData类型的有效数据,使用定义的接口可以存储路径到Tree结构中。

遍历的类型TreeTraverser,使用了一个栈来记录遍历的当前路径,其类型是自定义的TraverStack类型,表示一个节点和它未被遍历的孩子,栈中每个节点未遍历的孩子的序列实现上使用了一个vector序列容器记录,便于回溯的时候访问下一个未访问的孩子节点。

#include<iostream>
#include<stack>
#include<queue>
#include<cassert>
#include<algorithm>
using namespace std;

template<class TreeData>
struct Tree
{
	private:

		static int TreeDataCompare(Tree* op1, Tree* op2)
		{
			return op1->GetData() - op2->GetData();
		}

	public:
		Tree(TreeData data):
			m_data(data)
		{
		}

	public:
		void AppendChild(Tree* child)
		{
			m_children.push_back(child);

			// sort children trees by treedata
			sort(m_children.begin(), m_children.end(), TreeDataCompare);
		}

		Tree* PutChildByData(TreeData data)
		{
			// data already exists
			for(int i = 0; i < m_children.size(); i++)
				if(data == m_children[i]->GetData())
					return m_children[i];

			// Append new child to children array
			Tree* newChild = new Tree(data);
			AppendChild(newChild);

			return newChild;
		}

		void PutPathByDataArray(const TreeData* szData)
		{
			if (*szData == 0)
				return;

			Tree* child = PutChildByData(*szData);

			child->PutPathByDataArray(szData+1);
		}

	private:
		TreeData m_data;
		vector<Tree*> m_children;

	public:
		int GetChildrenNum()
		{
			return m_children.size();
		}

		Tree* GetChildByIndex(int index)
		{
			return m_children[index];
		}

		TreeData GetData()
		{
			return m_data;
		}

		// Fill children to the specified queue
		virtual void FillQueueWithChildren(queue<Tree*>& queue)
		{
			for(int i = 0; i < m_children.size(); i++)
			{
				if(m_children[i])
					queue.push(m_children[i]);
			}
		}
};

template<class Tree>
class TraverseStack
{
	public:
		TraverseStack(Tree* tree):
			m_tree(tree)
		{
			m_tree->FillQueueWithChildren(m_children);
		}

		Tree* GetNextChild()
		{
			if (m_children.empty())
				return NULL;

			// pop head of the untraversed children queue
			Tree* head = m_children.front();
			m_children.pop();

			return head;
		}

		Tree* GetTree()
		{
			return m_tree;
		}

	private:
		Tree* 			m_tree;
		queue<Tree*> 	m_children;
};

template<class Tree>
class BFSTraverser
{
	public:
		BFSTraverser(Tree* root):m_root(root){}
		virtual ~BFSTraverser(){}

	public:
		typedef TraverseStack<Tree> PATHSTACKITEM;
		typedef vector<PATHSTACKITEM > PATHSTACK;

	public:
		virtual void Traverse()
		{
			m_pathStack.clear();

			// push the root stack item
			PATHSTACKITEM rItem(m_root);
			m_pathStack.push_back(rItem);

			while(!m_pathStack.empty())
			{
				PATHSTACKITEM& top = m_pathStack.back();
				//cout << "Get top = " << top.GetTree()->GetData() << endl;

				Tree* nextChild = top.GetNextChild();
				if (!nextChild)
				{
					// output pathStack
					if(top.GetTree()->GetChildrenNum() == 0)
						OutputStack();

					// go back along the path to parent TraverseStack element
					m_pathStack.pop_back();
					continue;
				}

				assert(nextChild);

				// pre order output root‘s path
				if(nextChild == top.GetTree()->GetChildByIndex(0))
					;//OutputStack();

				// push new TraverseStack element to path
				PATHSTACKITEM newStackItem(nextChild);

				// enlonger the current path to the untraversed child
				m_pathStack.push_back(newStackItem);
				continue;
			}
		}		

	private:
		void OutputStack()
		{
			for(int i = 1; i < m_pathStack.size(); i++)
			{
				if(i>0)
					;//cout << ",";

				cout << m_pathStack[i].GetTree()->GetData();
			}
			cout << endl;
		}

	private:
		Tree* m_root;
		PATHSTACK m_pathStack;

};
时间: 2024-10-15 14:17:34

深度优先遍历多叉树结构,输出叶子路径的相关文章

遍历树,找出所有叶子路径

一.示例: 树的结构: 示例中自己构建了图片中的这棵树: 树节点模型: public class TreeNode { String value; List<TreeNode> children; public TreeNode() { children = new ArrayList<>(); } public TreeNode(String value) { this.value = value; children = new ArrayList<>(); } @O

以邻接表作为存储结构的图的深度优先遍历和广度优先遍历(c++版)

一.图的存储 用邻接表法存储图,存储结构分为两部分,一部分为存储图的所有顶点的数组,另一部分为挂载在数组的每个元素后面的用来表示顶点的邻接点的链表. 1.存储顶点的结构单元为: class vnode { public: string nodename; bool visted;//进行图的遍历时用于标记图是否被访问过 node *next; vnode() { visted = false; next = NULL; } }; 链表的结构单元为: class node { public: st

Python:遍历输出某路径下的所有文件和文件夹

怎么遍历输出某路径下的所有问价和文件夹? 这个问题和,"指定一个节点,输出以这个节点作为根节点的这棵树的所有子节点"一样. 递归可以实现. 如果是叶子节点(文件)了,就输出这个叶子节点的名称,返回. 否则,输出这个节点的名称(文件夹),并以这个结点再次作为根节点,遍历输出它的所有子节点. -- coding: utf-8 -- import os def traverse(f):fs = os.listdir(f)for f1 in fs:tmp_path = os.path.join

数据结构(C实现)------- 图的深度优先遍历

[本文是自己学习所做笔记,欢迎转载,但请注明出处:http://blog.csdn.net/jesson20121020] 算法描述: 假设给定图G的初始状态是所有顶点均未曾访问过,在G中任选一顶点vi为初始的出发点,则深度优先遍历可定义如下: 首先访问出发点vi,并将其标记为已被访问过:然后,依次从vi出发遍历vi的每一个邻接点vj,若vj未曾访问过,则以vj为新的出发点继续进行深度优先遍历,直至图中所有和vi有路径相通的顶点都被访问到为止.因此,若G是连通图,则从初始出发点开始的遍历过程结束

二分搜索树的深度优先遍历和广度优先遍历

二分搜索树的特点 二分搜索树首先是一个二叉树,其次其必须满足的条件是:每个节点的键值必须大于其左子节点,每个节点的键值必须小于其右子节点,这样以左右孩子为根的子树仍为二分搜索树,需要注意的是,二分搜索树不一定是一颗完全二叉树. 深度优先遍历 深度优先遍历的基本思想:对每一个可能的分支路径深入到不能再深入为止,而且每个结点只能访问一次.深度优先遍历的非递归的通用做法是采用栈.要特别注意的是,二分搜索树的深度优先遍历比较特殊,可以细分为前序遍历.中序遍历.后序遍历. 前序遍历:先访问当前节点,再依次

邻接矩阵的深度优先遍历

摘要:对<大话数据结构>P240——邻接矩阵的深度优先遍历,进行了自己的理解并完善了代码.Qt Creator测试通过. 举个简单的无序图例子,为了节省时间传手稿. 首先用邻接矩阵的存储结构创建该图,再进行深度优先遍历.代码和解释如下: #include <iostream> #include <stdlib.h> using namespace std; typedef struct//图的邻接矩阵存储结构 { char vexs[5]; int arc[5][5];

邻接表的深度优先遍历

转载请注明出处http://www.cnblogs.com/hslzju 对<大话数据结构>P241——邻接表的深度优先遍历,进行了自己的理解并完善了代码. 邻接矩阵的深度优先遍历见http://www.cnblogs.com/hslzju/p/5399249.html 举个简单的无序图例子,为了节省时间传手稿. 首先用邻接表的存储结构创建该图,再进行深度优先遍历.代码和解释如下(Qt Creator测试通过): 1 #include <iostream> 2 #include &

邻接矩阵的深度优先遍历(java版)

这是一个有向边带权的图 顶点数组:[v0, v1, v2, v3, v4] 边数组: v0 v1 v2 v3 v4 v0 6 v1 9 3 v2 2 5 v3 1 v4 package com.datastruct; import java.util.Scanner; public class MGraph { //定义图结构,使用邻接矩阵存储 private static class Graph{ final int MAXVEX = 10;//最大顶点数 final int INFINITY

C++实现图的邻接矩阵的创建以及其深度优先遍历和广度优先遍历

#include<iostream> using namespace std; typedef char vertextype; typedef int edgetype; #define maxvex 100 #define infinity 1000 #include<queue> int visited[100]; class MGraph{ public: vertextype vexs[maxvex]; edgetype arc[maxvex][maxvex]; int