mysql深度优先遍历储存过程_深度优先遍历多叉树结构,输出叶子路径

本文探讨了如何使用深度优先遍历算法在多叉树中寻找前缀匹配的路径,以实现在中文词汇查找中的高效应用。通过实例展示了如何构建字典树并利用自定义的TraverStack进行遍历,输出所有叶子节点作为匹配词条。
摘要由CSDN通过智能技术生成

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

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

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

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

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

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

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

#include

#include

#include

#include

#include

using namespace std;

template

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 

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 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& queue)

{

for(int i = 0; i 

{

if(m_children[i])

queue.push(m_children[i]);

}

}

};

template

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 m_children;

};

template

class BFSTraverser

{

public:

BFSTraverser(Tree* root):m_root(root){}

virtual ~BFSTraverser(){}

public:

typedef TraverseStack PATHSTACKITEM;

typedef vector 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 <GetData() <

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 

{

if(i>0)

;//cout <

cout <GetData();

}

cout <

}

private:

Tree* m_root;

PATHSTACK m_pathStack;

};

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值