Tree 如何在二叉树上获得从根到给定节点的路径?
我试图找出如何在二叉树上获得从根到给定节点的路径 它不是二进制搜索树 每个非叶节点只有两个指向其子节点的指针 顺序、预顺序、后顺序遍历不起作用 我试着做预订单,但不知道怎么做。例如,我们有一个二叉树: 它不是一个二进制搜索树。我们使用排序顺序节点使查找路径更容易Tree 如何在二叉树上获得从根到给定节点的路径?,tree,binary-tree,Tree,Binary Tree,我试图找出如何在二叉树上获得从根到给定节点的路径 它不是二进制搜索树 每个非叶节点只有两个指向其子节点的指针 顺序、预顺序、后顺序遍历不起作用 我试着做预订单,但不知道怎么做。例如,我们有一个二叉树: 它不是一个二进制搜索树。我们使用排序顺序节点使查找路径更容易 1 / \ 2 3 / \ / \ 4 5 6 7 我们希望找到从1到7的路径: 通过预购,我们有: 1 -> 2 -> 4 -> 5 -> 3 -> 6
1
/ \
2 3
/ \ / \
4 5 6 7
我们希望找到从1到7的路径:
通过预购,我们有:
1 -> 2 -> 4 -> 5 -> 3 -> 6 -> 7
从这个流中,我们得到了1->7的路径,所有节点都在上面
显然,这不应该
非常感谢您的帮助。预序遍历,也就是所谓的深度优先搜索确实有效
- 如果以递归方式实现前序遍历,那么当到达所需节点时,可以展开堆栈(递归调用)并反向构造路径
- 如果以非递归方式实现预序遍历,那么将直接构建堆栈,因此在这种情况下,一旦到达所需节点,就已经有了路径
- 从1开始,将其推到堆栈上,堆栈现在为[1]
- 向左走到2,将其推到堆栈上,堆栈现在为[12]
- 向左走到4号,按它,堆栈现在是[1 2 4]
- 这里没有4个孩子,这不是你想要的,所以弹出它,堆栈现在是[12]
- 现在您回到2,并且已经向左走了,现在向右走,堆栈现在是[1 2 5]
- 没有5岁的孩子,所以pop,stack现在是[12]
- 你已经耗尽了2个孩子的能量,所以弹出它,堆栈现在是[1]
- 现在你回到1,你已经完成了左边,所以向右走到3,推它,堆栈现在是[13]
- 向左走,堆栈现在是[1 3 6]
- 6是一片叶子,不是你要找的,所以pop,stack是[13]
- 现在你必须从3向右推,堆栈现在是[1 3 7]
- 但是等等!看!您已到达要查找的节点!看看你的书堆!这是你想要的路
- 您将获得一个二叉树(根节点)。。并且给出了一个键,该键可能在树中,也可能不在树中。
您必须找到从根到节点的完整路径
例如:
A
/ \
B C
\ /
D E
/ \ \
K L M
/
Z
您已经指定了节点Z(或节点的键)和节点A(根)
所以你的输出应该是
A B D K Z
如果给定M,则输出应为
A C E M
公共类主类{
公共静态void main(字符串参数[]){
//首先创建树
Node rootNode=新节点('A',新节点('B',null,
新节点('D',
新节点('K',
新节点('Z',空,
空),空),
新节点('L',null,null)),
新节点('C',
新节点('E',
无效的
新节点('M',null,null)),null));
ArrayList路径=新建ArrayList();
System.out.println(getPath(rootNode,'Z',path));
System.out.println(路径);
路径=新的ArrayList();
System.out.println(getPath(rootNode,'M',path));
System.out.println(路径);
}
静态布尔getPath(节点根节点、字符键、ArrayList路径){
//如果找到节点,则返回true
if(rootNode==null)
返回false;
if(rootNode.getVal()==键){
add(rootNode);
返回true;
}
布尔left\u check=getPath(rootNode.left,key,path);
布尔右键检查=getPath(rootNode.right,key,path);
如果(左检查| |右检查){
add(rootNode);
返回true;
}
返回false;
}
静态类节点{
char-val;
左淋巴结;
节点权;
公共节点(字符值、左节点、右节点){
这个。左=左;
这个。右=右;
这个.val=val;
}
公共字符getVal(){
返回val;
}
公共字符串toString(){
返回“+val+”;
}
}
}
公共列表getPath(T数据){
堆栈=新堆栈();
Boolean found=getPath(根、堆栈、数据);
列表路径=新的ArrayList();
如果(!找到){
返回路径;
}
返回Arrays.asList(stack.toArray((Node[])新节点[stack.size()]);
}
公共布尔getPath(节点、堆栈、T数据){
if(node==null){
返回false;
}
栈推(节点);
if(node.data.equals(data)){
返回true;
}
Boolean found=getPath(node.left、stack、data)||
getPath(node.right、堆栈、数据);
如果(!找到){
stack.pop();
}
发现退货;
}
考虑以下树:
10
/ \
8 2
/ \ /
3 5 2
方法
- 我们从根开始,将其与键进行比较,如果匹配,则打印路径(如果树只有一个节点,则路径仅包含根)
- 否则,将节点推入Vector(我认为Vector用于存储路径)
- 递归地在树的左侧和右侧移动
void PrintPath(node* root, vector <int> v,int key)
{
if(!root)
return;
if(root->data==key)
{
v.push_back(root->data);
vector<int>:: iterator it;
for(it=v.begin();it<v.end();it++)
{
cout<<*it<<" ";
}
return;
}
v.push_back(root->data);
PrintPath(root->left,v,key);
PrintPath(root->right,v,key);
}
void打印路径(节点*根,向量v,int键)
{
如果(!root)
返回;
如果(根->数据==键)
{
v、 向后推(根->数据);
向量::迭代器;
对于(it=v.begin();it在Java中有3种解决方案:
第一种是递归方法,第二种是使用2个satck,最后一种是使用2个队列。希望这对我有所帮助
10
/ \
8 2
/ \ /
3 5 2
void PrintPath(node* root, vector <int> v,int key)
{
if(!root)
return;
if(root->data==key)
{
v.push_back(root->data);
vector<int>:: iterator it;
for(it=v.begin();it<v.end();it++)
{
cout<<*it<<" ";
}
return;
}
v.push_back(root->data);
PrintPath(root->left,v,key);
PrintPath(root->right,v,key);
}