二叉树最长路径问题

本文介绍两种求解二叉树中最长路径的算法:非递归方式利用层次遍历和队列记录节点及其父节点;递归方式通过深度优先搜索进行节点遍历并记录路径。两种方法均能有效找到最长路径。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

已知一颗二叉树其定义如下:

struct node1{
int val;
node1*left;
node1*right;
};
例如:

                            A

                            | |

                           |   |

                          |     |

                         B     C  

                          |       |

                         |       |   |

                       D       E    F

                         |

                           |

                              G

采用二叉树存储结构,设计一个算法,输出该二叉树第一条最长路径信息。

方法一 采用非递归方式

这里先定义一个结构体:

struct snode{
node1*node;
int parent;
};
采用层次遍历,设计的对列为非环形顺序队列,将所有的点扫描入队,并记录每个点父节点的位置(方便回溯输出路径)

int longestpath(node1*r){
if(r==NULL)return 0;
struct snode{
    node1*node;
    int parent;
            }qu[20],tmp[20];
int front=-1,rear=-1;
int t;
bool f=0;
node1*p;
int i=0;
int len=0,maxlen=0;
rear++;
qu[rear].node=r;qu[rear].parent=-1;
while(front<rear){
  front++;
 p=qu[front].node;
 if(p->left==NULL&&p->right==NULL){len=0;t=front;
                                  len++;
				  while(qu[t].parent!=-1){t=qu[t].parent;len++;}
				  //cout<<len<<endl;
				  if(len>maxlen){maxlen=len;t=front;i=0;
				      while(i<maxlen&&qu[t].parent!=-1){tmp[i++]=qu[t];t=qu[t].parent;}
				      tmp[i]=qu[t];
				                 }
                                  }
 if(p->left){rear++;qu[rear].node=p->left;qu[rear].parent=front;}
 if(p->right){rear++;qu[rear].node=p->right;qu[rear].parent=front;}
                  }
cout<<"最长路径:"<<endl;
for(i=0;i<maxlen;i++)
    cout<<tmp[i].node->key<<" ";
return maxlen;
}
输出最长路径 G-D-B-A,最长距离4

方法二 递归方式

递归方式是处理二叉树问题的常用方法,容易想到,但是开销较大。由于需要输出路径,故参数需要引入路径数组以便记录。

void longestpath1(node1*r,char path[],int len,char longpath[],int &longlen){
int i;
if(r==NULL){
 if(len>longlen){for(i=0;i<len;i++)longpath[i]=path[i];}
 longlen=len;
        }
else{
    path[len]=r->key;
    len++;
    longestpath1(r->left,path,len,longpath,longlen);
    longestpath1(r->right,path,len,longpath,longlen);
    len--;
    }
}





### 关于二叉树最长路径的C语言实现 在解决二叉树最长路径问题时,通常可以通过递归方法来完成。以下是基于引用内容以及专业知识设计的一个完整的解决方案。 #### 定义二叉树结构 首先定义二叉树的数据结构如下: ```c typedef char ElemType; typedef struct BinNode { ElemType data; struct BinNode *lchild, *rchild; } BinNode, *BinTree; ``` 此部分来源于对二叉树基本结构的理解[^4]。 --- #### 计算二叉树的高度(间接用于最长路径) 为了找到最长路径,我们需要知道二叉树的高度。通过递归函数 `GetHeight` 可以获取某一节点的高度: ```c int GetHeight(BinTree root) { if (root == NULL) return 0; int leftHeight = GetHeight(root->lchild); int rightHeight = GetHeight(root->rchild); return (leftHeight > rightHeight ? leftHeight : rightHeight) + 1; } ``` 上述代码实现了计算某个节点高度的功能,这是后续寻找最长路径的基础之一[^5]。 --- #### 寻找最长路径的核心逻辑 对于一条路径而言,其可能经过根节点或者完全位于左子树/右子树内部。因此我们采用后序遍历的方式,在访问当前节点之前先处理它的左右孩子,并记录下每条路径上的最大值。 下面展示了一个具体的算法框架及其解释说明: ```c #include <stdio.h> #include <stdlib.h> // 声明全局变量 maxPathLength 来保存最终的结果 static int maxPathLength; void FindLongestPathUtil(BinTree node, int currentLength) { if (!node) { // 如果到达空节点,则更新最大长度并返回 if (currentLength > maxPathLength) { maxPathLength = currentLength; } return; } // 当前层的操作:增加路径长度计数器 currentLength++; // 对左右子树分别调用FindLongestPathUtil 函数继续探索更深层次 FindLongestPathUtil(node->lchild, currentLength); FindLongestPathUtil(node->rchild, currentLength); } void FindLongestPath(BinTree root){ maxPathLength=0;// 初始化最大路径长度为零 FindLongestPathUtil(root,0);// 调用辅助函数开始搜索过程 } ``` 以上代码片段展示了如何利用递归来追踪从根至叶的不同路径,并动态维护一个表示已知最远距离的整型数值maxPathLength 。每当遇到新的更深的位置就刷新这个纪录直到整个树都被扫描完毕为止[^1]。 注意这里并没有直接输出具体哪几个结点构成了所谓的“最长”,如果还需要额外提供这样的信息的话则需稍作修改加入相应的存储机制比如数组之类的容器类型用来暂存沿途所经之处的信息以便最后呈现出来。 --- ### 性能分析与注意事项 这种方法的时间复杂度主要取决于它要执行多少次基础操作——即每次都要比较两个孩子的高低然后加一再传回去给上级调用者;而空间消耗方面由于采用了标准形式的递归所以会占用一定的堆栈资源量级大约等于O(h),其中h代表目标二叉树的实际高矮程度[^3]。 另外值得注意的是本方案默认输入已经构建好的一棵合法有效的二叉链接列表作为起点参数传递进来,实际应用当中也许需要考虑更多边界情况例如非法指针指向NULL等问题预防潜在崩溃风险发生。 ---
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值