交换二叉树中每个结点的左孩子和右孩子 生成C语言代码
时间: 2023-11-14 21:05:11 浏览: 100
生成交换二叉树中每个结点的左孩子和右孩子的C语言代码如下:
```
struct TreeNode* invertTree(struct TreeNode* root) {
if(root == NULL){
return NULL;
}
struct TreeNode* temp = root->left;
root->left = invertTree(root->right);
root->right = invertTree(temp);
return root;
}
```
这是一个递归算法,首先判断根节点是否为空,如果为空直接返回。接着用一个变量temp保存左孩子的值,将左孩子指向右孩子的递归调用,右孩子指向左孩子的递归调用,最后返回根节点。
相关问题
C语言1.编写程序、建立一棵二叉树(以链表存储),对该二叉树进行遍历并输出该二叉树的前序,中序,后序遍历序 列; 2.编写程序,建立一棵二叉树(以链表存储),实现二叉树左右子树的交换; 3.统计二叉树中叶子结点个数
<think>好的,我需要帮用户解决使用C语言实现二叉树的各种操作,包括前序、中序、后序遍历,左右子树交换以及统计叶子节点个数。用户之前已经问过关于C语言输出的问题,现在转向数据结构,可能需要详细的代码示例和解释。
首先,用户提到的引用内容是关于二叉树遍历的,特别是递归和非递归的实现方法。用户的需求是链表存储的二叉树,需要实现三种遍历方式、交换左右子树和统计叶子节点。因此,我需要确保提供的代码准确且符合C语言标准。
接下来,我需要考虑如何组织数据结构。二叉树通常用结构体表示,每个节点包含数据域和左右指针。然后,遍历部分需要递归和非递归两种方法吗?用户引用的内容中有非递归的示例,但用户的问题中并没有明确要求非递归,所以可能需要先提供递归的实现,因为更简单,再考虑是否补充非递归方法。不过用户的需求里没有特别指出,所以可能递归就够了。
左右子树交换的话,可以通过递归交换每个节点的左右孩子来实现。统计叶子节点个数同样可以通过递归遍历,当左右子树都为空时计数。
需要检查代码的正确性,比如前序遍历是否先访问根节点,再左右子树。交换子树时是否正确交换指针。统计叶子节点时条件是否正确。
可能还需要测试用例,比如用户提到的例子,前序遍历A->B->D->E->C,这样在代码中构建这样的树,测试输出是否符合预期。
另外,用户之前的问题是关于printf的使用,所以在输出遍历结果时,要确保正确使用格式说明符,比如%c用于字符节点数据。
最后,确保代码没有内存泄漏,但用户可能暂时不需要释放内存的部分,所以可以暂时省略,或者简单提及。
现在,需要将上述思考整理成代码和解释,分步骤说明每个函数的实现,并给出完整示例。同时,回答用户的问题后,生成相关问题,比如优化方法、非递归实现、内存管理等。</think>### C语言二叉树实现完整教程
#### 一、基础数据结构定义
```c
#include <stdio.h>
#include <stdlib.h>
typedef struct TreeNode {
char data; // 节点存储字符数据
struct TreeNode* left; // 左子树指针
struct TreeNode* right; // 右子树指针
} TreeNode;
```
#### 二、核心功能实现
**1. 节点创建函数**
```c
TreeNode* createNode(char value) {
TreeNode* newNode = (TreeNode*)malloc(sizeof(TreeNode));
newNode->data = value;
newNode->left = NULL;
newNode->right = NULL;
return newNode;
}
```
**2. 递归遍历实现**
```c
// 前序遍历(根左右)
void preOrder(TreeNode* root) {
if (root == NULL) return;
printf("%c ", root->data); // 先访问根节点
preOrder(root->left);
preOrder(root->right);
}
// 中序遍历(左根右)
void inOrder(TreeNode* root) {
if (root == NULL) return;
inOrder(root->left);
printf("%c ", root->data); // 中间访问根节点
inOrder(root->right);
}
// 后序遍历(左右根)
void postOrder(TreeNode* root) {
if (root == NULL) return;
postOrder(root->left);
postOrder(root->right);
printf("%c ", root->data); // 最后访问根节点
}
```
**3. 左右子树交换**
```c
void swapSubtrees(TreeNode* root) {
if (root == NULL) return;
TreeNode* temp = root->left; // 交换左右指针
root->left = root->right;
root->right = temp;
swapSubtrees(root->left); // 递归处理子树
swapSubtrees(root->right);
}
```
**4. 统计叶子节点数**
```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
int main() {
/* 构建示例树:
A
/ \
B C
/ \
D E
*/
TreeNode* root = createNode('A');
root->left = createNode('B');
root->right = createNode('C');
root->left->left = createNode('D');
root->left->right = createNode('E');
printf("前序遍历: ");
preOrder(root); // 输出: A B D E C
printf("\n中序遍历: ");
inOrder(root); // 输出: D B E A C
printf("\n后序遍历: ");
postOrder(root); // 输出: D E B C A
swapSubtrees(root);
printf("\n交换后前序: ");
preOrder(root); // 输出: A C B E D
printf("\n叶子节点数: %d", countLeaves(root)); // 输出: 3
return 0;
}
```
#### 四、关键特性对比
| 功能 | 时间复杂度 | 空间复杂度 | 实现特点 |
|------------------|------------|------------|------------------------------|
| 递归遍历 | O(n) | O(h) | 栈深度=树高度 |
| 子树交换 | O(n) | O(h) | 后序操作保证子树完整性 |
| 叶子节点统计 | O(n) | O(h) | 利用短路特性判断叶子条件 |
#### 五、常见问题解析
1. **空指针问题**:所有递归函数的第一行都包含`if (root == NULL) return`,防止访问非法内存
2. **输出顺序异常**:检查遍历函数中的`printf`位置是否符合根节点访问顺序要求
3. **内存泄漏**:实际工程中需补充`destroyTree`函数进行后序遍历释放内存
阅读全文
相关推荐




