c语言实验: 二叉树基本操作 实验要求: 1.按先序序列构造一棵二叉链表表示的二叉树T; 2.对这棵二叉树进行递归遍历:先序、中序、后序以及层次遍历遍历序列,分别输出结点的遍历序列; 3. 对这棵树用非递归方式进行遍历:先序、中序以及后序遍历序列,分别输出结点的遍历序列; 4.求二叉树的深度/结点数目/叶结点数目; 5.将二叉树每个结点的左右子树交换位置; 6. 设计二叉树的双序遍历算法(双序遍历是指对于二叉树的每一个结点来说,先访问这个结点,再按双序遍历它的左子树,然后再一次访问这个结点,接下来按双序遍历它的右子树); 7. 计算二叉树最大宽度(二叉树的最大宽度是指二叉树所有层中结点个数的最大值); 8. 求二叉树中第一条最长的路径长度,并输出此路径上各结点。
时间: 2023-11-27 09:52:12 浏览: 50
附录1-基础实验.zip
很好,这是一个比较全面的二叉树操作实验。首先需要明确的是,二叉树的基本操作是遍历和统计,而遍历有递归和非递归两种方式,统计则需要考虑树的深度、节点数目、叶节点数目、最大宽度、最长路径等。
以下是一份参考代码,供你参考:
```c
#include <stdio.h>
#include <stdlib.h>
// 二叉树结点定义
typedef struct TreeNode {
int val;
struct TreeNode* left;
struct TreeNode* right;
} TreeNode;
// 先序遍历(递归)
void preorderTraversal(TreeNode* root) {
if (!root) return;
printf("%d ", root->val);
preorderTraversal(root->left);
preorderTraversal(root->right);
}
// 中序遍历(递归)
void inorderTraversal(TreeNode* root) {
if (!root) return;
inorderTraversal(root->left);
printf("%d ", root->val);
inorderTraversal(root->right);
}
// 后序遍历(递归)
void postorderTraversal(TreeNode* root) {
if (!root) return;
postorderTraversal(root->left);
postorderTraversal(root->right);
printf("%d ", root->val);
}
// 层次遍历
void levelTraversal(TreeNode* root) {
if (!root) return;
queue<TreeNode*> q;
q.push(root);
while (!q.empty()) {
TreeNode* cur = q.front();
q.pop();
printf("%d ", cur->val);
if (cur->left) q.push(cur->left);
if (cur->right) q.push(cur->right);
}
}
// 先序遍历(非递归)
void preorderTraversal2(TreeNode* root) {
if (!root) return;
stack<TreeNode*> s;
s.push(root);
while (!s.empty()) {
TreeNode* cur = s.top();
s.pop();
printf("%d ", cur->val);
if (cur->right) s.push(cur->right);
if (cur->left) s.push(cur->left);
}
}
// 中序遍历(非递归)
void inorderTraversal2(TreeNode* root) {
if (!root) return;
stack<TreeNode*> s;
TreeNode* cur = root;
while (cur || !s.empty()) {
while (cur) {
s.push(cur);
cur = cur->left;
}
cur = s.top();
s.pop();
printf("%d ", cur->val);
cur = cur->right;
}
}
// 后序遍历(非递归)
void postorderTraversal2(TreeNode* root) {
if (!root) return;
stack<TreeNode*> s1, s2;
s1.push(root);
while (!s1.empty()) {
TreeNode* cur = s1.top();
s1.pop();
s2.push(cur);
if (cur->left) s1.push(cur->left);
if (cur->right) s1.push(cur->right);
}
while (!s2.empty()) {
printf("%d ", s2.top()->val);
s2.pop();
}
}
// 求深度
int maxDepth(TreeNode* root) {
if (!root) return 0;
int leftDepth = maxDepth(root->left);
int rightDepth = maxDepth(root->right);
return 1 + (leftDepth > rightDepth ? leftDepth : rightDepth);
}
// 求节点数目
int countNodes(TreeNode* root) {
if (!root) return 0;
return 1 + countNodes(root->left) + countNodes(root->right);
}
// 求叶节点数目
int countLeaves(TreeNode* root) {
if (!root) return 0;
if (!root->left && !root->right) return 1;
return countLeaves(root->left) + countLeaves(root->right);
}
// 交换左右子树
void swapChildren(TreeNode* root) {
if (!root) return;
TreeNode* tmp = root->left;
root->left = root->right;
root->right = tmp;
swapChildren(root->left);
swapChildren(root->right);
}
// 双序遍历
void doubleOrderTraversal(TreeNode* root) {
if (!root) return;
printf("%d ", root->val);
doubleOrderTraversal(root->left);
printf("%d ", root->val);
doubleOrderTraversal(root->right);
}
// 求最大宽度
int maxWidth(TreeNode* root) {
if (!root) return 0;
queue<TreeNode*> q;
q.push(root);
int maxWidth = 1;
while (!q.empty()) {
int size = q.size();
if (size > maxWidth) maxWidth = size;
while (size--) {
TreeNode* cur = q.front();
q.pop();
if (cur->left) q.push(cur->left);
if (cur->right) q.push(cur->right);
}
}
return maxWidth;
}
// 求最长路径长度
int maxPathLen(TreeNode* root, int* maxLen, TreeNode** maxNode) {
if (!root) return 0;
int leftLen = maxPathLen(root->left, maxLen, maxNode);
int rightLen = maxPathLen(root->right, maxLen, maxNode);
int curLen = leftLen + rightLen + 1;
if (curLen > *maxLen) {
*maxLen = curLen;
*maxNode = root;
}
return 1 + (leftLen > rightLen ? leftLen : rightLen);
}
// 输出最长路径
void printMaxPath(TreeNode* node) {
if (!node) return;
printMaxPath(node->left);
printf("%d ", node->val);
printMaxPath(node->right);
}
// 构造二叉树
TreeNode* buildTree() {
int val;
scanf("%d", &val);
if (val == -1) return NULL;
TreeNode* root = (TreeNode*)malloc(sizeof(TreeNode));
root->val = val;
root->left = buildTree();
root->right = buildTree();
return root;
}
int main() {
// 构造二叉树
TreeNode* root = buildTree();
// 遍历(递归)
printf("Preorder traversal: ");
preorderTraversal(root);
printf("\n");
printf("Inorder traversal: ");
inorderTraversal(root);
printf("\n");
printf("Postorder traversal: ");
postorderTraversal(root);
printf("\n");
printf("Level traversal: ");
levelTraversal(root);
printf("\n");
// 遍历(非递归)
printf("Preorder traversal2: ");
preorderTraversal2(root);
printf("\n");
printf("Inorder traversal2: ");
inorderTraversal2(root);
printf("\n");
printf("Postorder traversal2: ");
postorderTraversal2(root);
printf("\n");
// 统计
printf("Max depth: %d\n", maxDepth(root));
printf("Node count: %d\n", countNodes(root));
printf("Leaf count: %d\n", countLeaves(root));
// 交换左右子树
swapChildren(root);
printf("After swapping children: ");
levelTraversal(root);
printf("\n");
// 双序遍历
printf("Double order traversal: ");
doubleOrderTraversal(root);
printf("\n");
// 最大宽度
printf("Max width: %d\n", maxWidth(root));
// 最长路径
int maxLen = 0;
TreeNode* maxNode = NULL;
maxPathLen(root, &maxLen, &maxNode);
printf("Max path length: %d\n", maxLen);
printf("Max path: ");
printMaxPath(maxNode);
printf("\n");
return 0;
}
```
注意,这份代码没有包含释放内存的代码。在实际应用中,需要注意内存泄漏问题。
希望这份代码能够帮助你完成实验。如果有任何问题,欢迎继续提问。
阅读全文