用C语言建立一个二叉树;按先序、中序、后序遍历二叉树(三种递归算法和中序遍历的非递归算法)
时间: 2024-05-03 17:21:00 浏览: 121
好的,这是一个经典的数据结构问题。首先我们来看如何用C语言建立一个二叉树。二叉树是由一个个结点组成的,每个结点有一个值和两个指向左右子树的指针。因此,我们可以定义一个二叉树的结点结构体:
```
struct TreeNode {
int val;
struct TreeNode* left;
struct TreeNode* right;
};
```
接下来,我们可以用递归的方式来建立二叉树。例如,我们可以定义一个函数CreateTree来创建一个二叉树,其中参数n表示当前层级,最初从0开始,max表示树的最大深度:
```
struct TreeNode* CreateTree(int n, int max) {
struct TreeNode* root = NULL;
if (n < max) {
root = (struct TreeNode*)malloc(sizeof(struct TreeNode));
root->val = n;
root->left = CreateTree(n * 2 + 1, max);
root->right = CreateTree(n * 2 + 2, max);
}
return root;
}
```
在CreateTree函数中,我们首先判断当前层级是否小于最大深度。如果是,就创建一个新的结点,并将当前层级作为结点的值。然后递归调用CreateTree函数,传入左右子树的层级,并将返回值赋给当前节点的左右子树指针。如果当前层级大于等于最大深度,则返回NULL。这样,我们就可以用CreateTree函数来创建一个有max层的满二叉树。
接下来,我们来看如何按先序、中序、后序遍历二叉树。三种递归算法分别如下:
```
// 先序遍历
void preorderTraversal(struct TreeNode* root) {
if (root != NULL) {
printf("%d ", root->val);
preorderTraversal(root->left);
preorderTraversal(root->right);
}
}
// 中序遍历
void inorderTraversal(struct TreeNode* root) {
if (root != NULL) {
inorderTraversal(root->left);
printf("%d ", root->val);
inorderTraversal(root->right);
}
}
// 后序遍历
void postorderTraversal(struct TreeNode* root) {
if (root != NULL) {
postorderTraversal(root->left);
postorderTraversal(root->right);
printf("%d ", root->val);
}
}
```
这三个函数都是递归函数,每个函数中都会先判断当前节点是否为空,如果不为空,则打印节点的值,并分别递归调用左右子树。不同的是,在先序遍历中,我们先访问根节点,然后再访问左子树和右子树;在中序遍历中,我们先访问左子树,然后访问根节点,最后访问右子树;在后序遍历中,我们先访问左子树,然后访问右子树,最后访问根节点。
最后,我们来看如何用非递归算法中序遍历二叉树。可以用一个栈来辅助实现。具体步骤如下:
1. 从根节点开始,将所有左子树节点入栈,直到最左侧的叶子节点。
2. 弹出栈顶节点并访问它。
3. 如果右子树不为空,则将右子树的所有左子树节点入栈,重复步骤2。
4. 如果右子树为空,则重复步骤2,直到栈为空。
下面是代码实现:
```
// 中序遍历(非递归)
void inorderTraversal(struct TreeNode* root) {
struct TreeNode* stack[100];
int top = -1;
while (root != NULL || top != -1) {
while (root != NULL) {
stack[++top] = root;
root = root->left;
}
root = stack[top--];
printf("%d ", root->val);
root = root->right;
}
}
```
在这段代码中,我们用一个数组来实现栈,并定义一个top指针表示栈顶。在while循环中,我们不断将左子树节点入栈,直到最左侧的叶子节点。然后弹出栈顶节点并访问它,如果它的右子树不为空,就将右子树所有的左子树节点入栈。否则,就继续弹出栈顶节点重复上述步骤。
阅读全文