设计两个算法,分别求二叉树在前序遍历下的最后一个结点以及后序遍历下的第一个结点。
时间: 2024-06-10 20:04:29 浏览: 41
回答您的问题,分别求二叉树在前序遍历下的最后一个结点以及后序遍历下的第一个结点的算法如下:
1. 前序遍历下的最后一个结点的算法:
(1) 判断当前结点是否有右子树,如果有,则递归遍历右子树,直到找到最后一个结点;
(2) 如果当前结点没有右子树,判断当前结点是否有父亲结点,如果没有,则当前结点为根结点,返回当前结点;如果有,则递归遍历父亲结点的右子树,直到找到最后一个结点。
2. 后序遍历下的第一个结点的算法:
(1) 判断当前结点是否有左子树,如果有,则递归遍历左子树,直到找到第一个结点;
(2) 如果当前结点没有左子树,判断当前结点是否有右子树,如果有,则递归遍历右子树,直到找到第一个结点;
(3) 如果当前结点既没有左子树又没有右子树,判断当前结点是否有父亲结点,如果没有,则当前结点为根结点,返回当前结点;如果有,则递归遍历父亲结点的右子树,直到找到第一个结点。
以上是我设计的两个算法,希望能对您有所帮助。
相关问题
1.用递归或非递归方式求二叉树中序遍历下的第一个点 2.用递归或非递归方式求二叉树中序遍历下的最后一个点 3.用递归设计算法统计二叉树中叶子结点个数
1. **二叉树中序遍历的第一个点(递归与非递归)**:
- 递归方式:
```c
// 中序遍历找首个节点(假设最小节点位于最左侧)
TreeNode* firstInOrder(TreeNode* root) {
if (root == NULL) return NULL;
if (root->left == NULL) return root;
return firstInOrder(root->left);
}
```
- 非递归方式(栈):
```c
TreeNode* firstInOrderNonRecursive(TreeNode* root) {
stack<TreeNode*> s;
TreeNode* first = NULL;
while (!s.isEmpty() || root != NULL) {
while (root != NULL) {
s.push(root);
root = root->left;
}
root = s.top();
s.pop();
if (first == NULL) first = root; // 栈顶第一个不是左孩子的就是第一个
root = root->right;
}
return first;
}
```
2. **二叉树中序遍历的最后一个点(递归与非递归)**:
- 递归方式:
```c
// 中序遍历找最后节点
TreeNode* lastInOrder(TreeNode* root) {
if (root == NULL) return NULL;
TreeNode* lastLeft = lastInOrder(root->left);
if (lastLeft == NULL) return root; // 如果左子树已经遍历完,当前节点是最后一个
return lastLeft;
}
```
- 非递归方式(需要辅助栈):
```c
TreeNode* lastInOrderNonRecursive(TreeNode* root) {
stack<TreeNode*> s1, s2;
TreeNode* last = NULL;
while (!s1.isEmpty() || root != NULL) {
while (root != NULL) {
s1.push(root);
root = root->left;
}
root = s1.top();
s1.pop();
while (!s1.isEmpty() && s1.top()->left == root) { // 移除所有等于当前节点的左兄弟
s2.push(s1.top());
s1.pop();
}
if (last == NULL) last = root; // 当前节点可能是最后一个
root = s2.empty() ? root->right : NULL; // 如果只剩右子树或栈已清空,说明是最后一个
}
return last;
}
```
3. **递归计算二叉树中叶子结点个数**:
```c
int countLeaves(TreeNode* root) {
if (root == NULL) return 0;
if (root->left == NULL && root->right == NULL) return 1; // 叶子节点
return countLeaves(root->left) + countLeaves(root->right);
}
```
这里直接判断每个节点是否有左右子节点即可。
用C语言1.用递归或非递归方式求二叉树中序遍历下的第一个点 2.用递归或非递归方式求二叉树中序遍历下的最后一个点 3.用递归设计算法统计二叉树中叶子结点个数
1. **使用递归求二叉树中序遍历的第一个点**:
中序遍历二叉树的顺序是左-根-右,递归实现时,可以在遍历左子树的过程中查找第一个节点。非递归版本需要借助栈来保存遍历过程。
递归版伪代码:
```c
int findFirstInOrder(Node* root) {
if (root == NULL) return NULL;
return findFirstInOrder(root->left) ?: root; // 如果左子树为空,则返回当前节点
}
```
非递归版伪代码:
```c
Node* findFirstInOrder(Node* root) {
stack<Node*> s;
Node* current = root;
while (!s.empty() || current != NULL) {
while (current != NULL) {
s.push(current);
current = current->left;
}
current = s.top();
s.pop();
current = current->right;
}
return current;
}
```
2. **使用递归求二叉树中序遍历的最后一个点**:
在中序遍历时,最后一个节点是遍历完右子树后回溯到根节点,再访问左子树直到找到空节点。递归实现时直接返回即可。
递归版伪代码:
```c
Node* findLastInOrder(Node* root) {
if (root == NULL) return NULL;
Node* lastRight = findLastInOrder(root->right);
if (lastRight != NULL) return lastRight;
return root;
}
```
3. **使用递归计算二叉树中叶子结点个数**:
叶子节点是没有子节点的节点,递归遍历时只要检查当前节点是否有左右孩子即可。
递归版伪代码:
```c
int countLeaves(Node* node) {
if (node == NULL) return 0;
else if (node->left == NULL && node->right == NULL) return 1; // 叶子节点
else return countLeaves(node->left) + countLeaves(node->right);
}
```
阅读全文