我正在尝试编写C ++代码,在给定多路树的情况下,该树会将其转换为left-child/right-sibling format中表示的二进制树。例如,给定这棵树:
A
/ | \
B C D
/ | \ |
E F G H
/ \
I J
我想输出这棵树:
A
/
B
/ \
E C
\ \
F D
/ \ /
I G H
\
J
我不确定如何解决此问题。我应该如何考虑呢?
答案 0 :(得分:0)
您可以使用很好的递归见解来解决此问题。由于我不知道您如何表示树,因此我将让您详细说明如何在代码中实际实现此方法,但这是核心思想。
首先,将一棵空树转换为LC / RS格式真的很容易:它以空树的形式出现。
另一方面,假设您有一棵非空树。首先将其每个子级转换为LC / RS格式(递归)。例如,给定这棵树:
A
/ | \
B C D
/ | \ |
E F G H
/ \
I J
首先,将每个孩子递归转换为LC / RS,并退还这三棵树:
B C D
/ /
E H
\
F
/ \
I G
\
J
这些树目前是自由浮动的,并且彼此之间没有链接。但是,由于您知道它们是兄弟姐妹,因此,您需要使C成为B的正确子代,而D使其成为C的正确子代。从本质上讲,这是一个链表遍历。完成后,事情应该是这样的:
B
/ \
E C
\ \
F D
/ \ /
I G H
\
J
完成此操作后,剩下要做的就是使B成为A的左孩子,如下所示:
A
/
B
/ \
E C
\ \
F D
/ \ /
I G H
\
J
回顾一下,逻辑如下:
我将保留C ++详细信息供您填写。如果您试图解决此问题并遇到麻烦,请随时发布后续问题,详细说明您编写的代码到目前为止,还有失败的特定测试用例或您遇到的特定编译器错误。祝你好运!
答案 1 :(得分:0)
假设
假设根据https://en.wikipedia.org/wiki/Binary_tree表示二叉树,而多路树类似于二叉树,但是具有可数的子节点,而不是可选的左右子节点,而算法根据https://en.wikipedia.org/wiki/Left-child_right-sibling_binary_tree
类型
类型可能是以下模板-用于多路树:
template <typename T>
class CMultiWayTree {
public:
typedef CMultiWayTree<T>* NodePtr;
typedef list<NodePtr> List;
public:
T m_tData;
protected:
List m_lNodes;
public:
// ...
};
...对于二叉树:
template <typename T>
class CBinaryTree {
public:
typedef CBinaryTree<T>* NodePtr;
public:
typedef CGeneralTree<T>* MTNodePtr;
public:
T m_tData;
protected:
NodePtr m_pLeftNode;
NodePtr m_pRightNode;
//...
};
代码
如果假设正确,则代码可能如下所示。而转换算法(“左子级右兄弟二叉树”)是在构造函数“ CBinaryTree(MTNodePtr pmtToConvert)”中实现的。
#include <iostream>
#include <list>
using namespace std;
string ident(int nDepth) {
string sIndent;
for (int n = 0; n < nDepth; n++) {
sIndent += ' ';
}
return sIndent;
}
template <typename T>
class CMultiWayTree {
public:
typedef CMultiWayTree<T>* NodePtr;
typedef list<NodePtr> List;
public:
T m_tData;
protected:
List m_lNodes;
public:
CMultiWayTree(const T& rtData) {
m_tData = rtData;
};
virtual ~CMultiWayTree() {
typename List::iterator it;
it = m_lNodes.begin();
while ( it != m_lNodes.end() ) {
delete (*it);
it++;
}
}
virtual const T& getNode() {
return m_tData;
};
virtual void goToFirstChildNode(typename List::iterator& it) {
it = m_lNodes.begin();
};
virtual void goToNextChildNode(typename List::iterator& it) {
it++;
};
virtual bool getChildNode(typename List::iterator& it, NodePtr& pNode) {
bool bIsChildNode;
bIsChildNode = it != (m_lNodes.end());
if ( bIsChildNode ) {
pNode = (*it);
} else {
pNode = NULL;
}
return bIsChildNode;
};
virtual NodePtr appendChildNode(const T& rtData) {
NodePtr pNode = new CMultiWayTree(rtData);
m_lNodes.push_back(pNode);
return pNode;
};
virtual void print(ostream& os, int nDepth = 0) {
NodePtr pNode;
typename List::iterator it;
os << ident(nDepth) << m_tData << endl;
nDepth++;
goToFirstChildNode(it);
while ( getChildNode(it, pNode) ) {
pNode->print(os, nDepth);
goToNextChildNode(it);
}
};
};
template <typename T>
class CBinaryTree {
public:
typedef CBinaryTree<T>* NodePtr;
public:
typedef CMultiWayTree<T>* MTNodePtr;
public:
T m_tData;
protected:
NodePtr m_pLeftNode;
NodePtr m_pRightNode;
public:
CBinaryTree(const T& rtData) {
m_tData = rtData;
m_pLeftNode = NULL;
m_pRightNode = NULL;
};
CBinaryTree(GTNodePtr pmtToConvert) {
if ( pmtToConvert != NULL ) {
NodePtr pNewNode;
MTNodePtr pNode;
typename CMultiWayTree<T>::List::iterator it;
m_tData = pmtToConvert->m_tData;
m_pRightNode = NULL;
pmtToConvert->goToFirstChildNode(it);
if ( pmtToConvert->getChildNode(it, pNode) ) {
pNewNode = new CBinaryTree(pNode);
m_pLeftNode = pNewNode;
pmtToConvert->goToNextChildNode(it);
} else {
m_pLeftNode = NULL;
}
while ( pmtToConvert->getChildNode(it, pNode) ) {
pNewNode = pNewNode->setRight(new CBinaryTree(pNode));
pmtToConvert->goToNextChildNode(it);
}
}
};
virtual ~CBinaryTree() {
if ( m_pLeftNode != NULL ) {
delete m_pLeftNode;
m_pLeftNode = NULL;
}
if ( m_pRightNode != NULL ) {
delete m_pRightNode;
m_pRightNode = NULL;
}
};
virtual NodePtr setRight(NodePtr pNew) {
if ( m_pRightNode != NULL ) {
delete m_pRightNode;
}
m_pRightNode = pNew;
return m_pRightNode;
}
virtual void print(ostream& os, int nDepth = 0, char chPreFix = '\0') {
NodePtr pNode;
if ( chPreFix != '\0' ) {
os << ident(nDepth - 1) << chPreFix << m_tData << endl;
} else {
os << ident(nDepth) << m_tData << endl;
}
nDepth++;
if ( m_pRightNode != NULL ) {
m_pRightNode->print(os, nDepth, 'r');
}
if ( m_pLeftNode != NULL ) {
m_pLeftNode->print(os, nDepth, 'l');
}
};
};
int main() {
CMultiWayTree<char>::NodePtr pMultiWayTreeNode = new CMultiWayTree<char>('A');
CMultiWayTree<char>::NodePtr pMultiWayTreeNodeB = pMultiWayTreeNode->appendChildNode('B');
CMultiWayTree<char>::NodePtr pMultiWayTreeNodeC = pMultiWayTreeNode->appendChildNode('C');
CMultiWayTree<char>::NodePtr pMultiWayTreeNodeD = pMultiWayTreeNode->appendChildNode('D');
CMultiWayTree<char>::NodePtr pMultiWayTreeNodeE = pMultiWayTreeNodeB->appendChildNode('E');
CMultiWayTree<char>::NodePtr pMultiWayTreeNodeF = pMultiWayTreeNodeB->appendChildNode('F');
CMultiWayTree<char>::NodePtr pMultiWayTreeNodeG = pMultiWayTreeNodeB->appendChildNode('G');
CMultiWayTree<char>::NodePtr pMultiWayTreeNodeH = pMultiWayTreeNodeD->appendChildNode('H');
CMultiWayTree<char>::NodePtr pMultiWayTreeNodeI = pMultiWayTreeNodeF->appendChildNode('I');
CMultiWayTree<char>::NodePtr pMultiWayTreeNodeJ = pMultiWayTreeNodeF->appendChildNode('J');
cout << "Input (multi-way tree):" << endl;
pMultiWayTreeNode->print(cout, 3);
cout << endl;
CBinaryTree<char>::NodePtr pBinaryTreeNode = new CBinaryTree<char>(pMultiWayTreeNode);
cout << "Output (binary tree):" << endl;
pBinaryTreeNode->print(cout, 3);
delete pMultiWayTreeNode;
delete pBinaryTreeNode;
return 0;
}
输出
程序将创建以下输出:
Input (multi-way tree):
A
B
E
F
I
J
G
C
D
H
Output (binary tree):
A
lB
rC
rD
lH
lE
rF
rG
lI
rJ