我正在做一个需要创建二叉树的任务。我的二进制逻辑正确,但是我对如何以及在何处创建树感到困惑。下面的屏幕快照是我当前的输出,我想将其做成树形,其根在顶部,然后向下。在这一点上,如果更容易进行横向调整,那么我什至会为此解决。
#include <iostream>
#include <string>
using namespace std;
class TreeNode
{
public:
void insert_node(TreeNode* new_node);
void print_nodes() const;
bool find(string value) const;
private:
string data;
TreeNode* left;
TreeNode* right;
friend class BinarySearchTree;
};
class BinarySearchTree
{
public:
BinarySearchTree();
void insert(string data);
void erase(string data);
int count(string data) const;
void print() const;
private:
TreeNode* root;
};
/*
BinarySearchTree Default constructor
*/
BinarySearchTree::BinarySearchTree()
{
root = NULL;
}
void BinarySearchTree::print() const
{
if (root != NULL)
{
root->print_nodes();
}
}
void BinarySearchTree::insert(string data)
{
// Creates a new node and sets values
TreeNode* new_node = new TreeNode;
// Saves data to new_node and pointers to NULL
new_node->data = data;
new_node->left = NULL;
new_node->right = NULL;
// sets root as node saved above
if (root == NULL)
{
root = new_node;
}
/*
If root has has been set then determine how to link new_node.
root is the parent node and new_node will be the child of root
*/
else root->insert_node(new_node);
}
void TreeNode::insert_node(TreeNode* new_node)
{
// this-> referrs to root node
if (new_node->data < this->data)
{
// Sets left node of root to
// point to new_node
if (this->left == NULL)
{
this->left = new_node;
}
// inserts a new node onto root->left
else this->left->insert_node(new_node);
}
else if (this->data < new_node->data)
{
if (this->right == NULL)
{
// inserts a new node onto root->right
this->right = new_node;
}
else this->right->insert_node(new_node);
}
}
int BinarySearchTree::count(string data) const
{
if (root == NULL) return 0;
else if (root->find(data)) return 1;
else return 0;
}
void BinarySearchTree::erase(string data)
{
// Find node to be removed
TreeNode* to_be_removed = root;
TreeNode* parent = NULL;
bool found = false;
while (!found && to_be_removed != NULL)
{
if (to_be_removed->data < data)
{
parent = to_be_removed;
to_be_removed = to_be_removed->right;
}
else if (data < to_be_removed->data)
{
parent = to_be_removed;
to_be_removed = to_be_removed->left;
}
else found = true;
}
if (!found) return;
// to_be_removed contains data
// If one of the children is empty, use the other
if (to_be_removed->left == NULL || to_be_removed->right == NULL)
{
TreeNode* new_child;
if (to_be_removed->left == NULL)
new_child = to_be_removed->right;
else
new_child = to_be_removed->left;
if (parent == NULL) // Found in root
root = new_child;
else if (parent->left == to_be_removed)
parent->left = new_child;
else
parent->right = new_child;
return;
}
// Neither subtree is empty
// Find smallest element of the right subtree
TreeNode* smallest_parent = to_be_removed;
TreeNode* smallest = to_be_removed->right;
while (smallest->left != NULL)
{
smallest_parent = smallest;
smallest = smallest->left;
}
// smallest contains smallest child in right subtree
// Move contents, unlink child
to_be_removed->data = smallest->data;
if (smallest_parent == to_be_removed)
smallest_parent->right = smallest->right;
else
smallest_parent->left = smallest->right;
}
bool TreeNode::find(string value) const
{
if (value < data)
{
if (left == NULL) return false;
else return left->find(value);
}
else if (data < value)
{
if (right == NULL) return false;
else return right->find(value);
}
else
return true;
}
void TreeNode::print_nodes() const
{
if (this->right != NULL)
{
cout << data << "\n" << "\\" << "\n" << this->right->data << " " << "\n";
this->right->print_nodes();
if (this->left != NULL)
{
cout << data << "\n" << "/" << "\n" << this->left->data << "\n";
this->left->print_nodes();
}
}
}
int main()
{
BinarySearchTree t;
t.insert("D");
t.insert("B");
t.insert("A");
t.insert("C");
t.insert("F");
t.insert("E");
t.insert("I");
t.insert("G");
t.insert("H");
t.insert("J");
t.print();
cout << "\n \n";
cout << "\n \n";
system("pause");
return 0;
}
最佳答案
有很多方法可以做到这一点。这是一个:
A
|-B
| |-C
| | |-H
| | `-I
| `-D
| |-F
| `-G
`-E
这里A有 child B和E.B有C和D.等等...
那么我们如何才能做到这一点呢?这是伪代码:
Let S = {} (an empty global set of integers)
procedure indent(level)
for i in [0..level)
if i \in S print "| "
else print " "
procedure tee(level)
indent(level)
print("|-")
S = S + { level }
procedure ell(level)
indent(level)
print("`-")
S = S - { level }
procedure print(node, level)
if node is null
print("[null]" with newline) // only prints when 1 child is missing
else
print(node label with newline)
if node has any children
tee(level)
print(node.left, level + 1)
ell(level)
print(node.right, level + 1)
设置跟踪哪些列需要竖线。每个“T形”形状都会开始一个垂直条。每个“ell”形状在同一列中都以一个结束。
该集合可以是 bool(boolean) 数组(字符),最初通过将其全部设置为零来使其为空。其余的几乎是对C的逐行转换。
我的快速结果是在一个包含31个节点的完整树上。
L0
|-L1
| |-L2
| | |-L3
| | | |-L4
| | | `-L5
| | `-L6
| | |-L7
| | `-L8
| `-L9
| |-L10
| | |-L11
| | `-L12
| `-L13
| |-L14
| `-L15
`-L16
|-L17
| |-L18
| | |-L19
| | `-L20
| `-L21
| |-L22
| `-L23
`-L24
|-L25
| |-L26
| `-L27
`-L28
|-L29
`-L30
对于普通读者来说,值得指出的是,此方法适用于带有子标签的N元树(例如,编译器中的抽象语法树)。在
ell
和tee
中添加一个子名称参数,并为除最后一个(保留为tee
)之外的每个子项调用ell
。