c语言打印二叉树形状
时间: 2024-10-19 13:13:18 浏览: 11
在C语言中,打印二叉树通常采用层次遍历(先序、中序或后序),因为这种方法可以较好地展示树的结构。这里以先序遍历(根节点 -> 左子树 -> 右子树)为例,假设有一个简单的二叉树结构定义:
```c
typedef struct TreeNode {
int val;
struct TreeNode* left;
struct TreeNode* right;
} TreeNode;
```
你可以编写如下的函数来递归打印二叉树的形状:
```c
void printPreorder(TreeNode* root) {
if (root != NULL) {
printf("%d ", root->val); // 打印当前节点值
printPreorder(root->left); // 递归左子树
printPreorder(root->right); // 递归右子树
}
}
```
如果你想在控制台上看到类似下图的形式:
```
1
/ \
2 3
/ \
4 5
```
你可以先创建一个这样的二叉树,然后调用`printPreorder`函数。
相关问题
用c语言编写简历二叉树,输出二叉树,输出二叉树形状,先序遍历并打印,层次遍历并打印,计算节点数,计算叶子节点数,计算数的深度的相关代码
以下是用C语言编写的简历二叉树的相关代码:
```c
#include <stdio.h>
#include <stdlib.h>
// 定义二叉树节点结构体
typedef struct TreeNode {
int data;
struct TreeNode *left;
struct TreeNode *right;
} TreeNode, *TreeNodePtr;
// 创建一个新的二叉树节点
TreeNodePtr createNode(int data) {
TreeNodePtr node = (TreeNodePtr) malloc(sizeof(TreeNode));
node->data = data;
node->left = NULL;
node->right = NULL;
return node;
}
// 插入节点
TreeNodePtr insertNode(TreeNodePtr root, int data) {
if (root == NULL) {
root = createNode(data);
} else if (data < root->data) {
root->left = insertNode(root->left, data);
} else if (data > root->data) {
root->right = insertNode(root->right, data);
}
return root;
}
// 输出二叉树
void printTree(TreeNodePtr root, int level) {
if (root != NULL) {
printTree(root->right, level + 1);
for (int i = 0; i < level; i++) {
printf(" ");
}
printf("%d\n", root->data);
printTree(root->left, level + 1);
}
}
// 输出二叉树形状
void printShape(TreeNodePtr root, int level) {
if (root != NULL) {
printShape(root->right, level + 1);
for (int i = 0; i < level; i++) {
printf(" ");
}
printf("%d\n", root->data);
printShape(root->left, level + 1);
} else {
printf("\n");
}
}
// 先序遍历并打印
void preorderTraversal(TreeNodePtr root) {
if (root != NULL) {
printf("%d ", root->data);
preorderTraversal(root->left);
preorderTraversal(root->right);
}
}
// 层次遍历并打印
void levelTraversal(TreeNodePtr root) {
if (root == NULL) {
return;
}
TreeNodePtr queue[100];
int front = 0, rear = 0;
queue[rear++] = root;
while (front < rear) {
TreeNodePtr node = queue[front++];
printf("%d ", node->data);
if (node->left != NULL) {
queue[rear++] = node->left;
}
if (node->right != NULL) {
queue[rear++] = node->right;
}
}
}
// 计算节点数
int countNodes(TreeNodePtr root) {
if (root == NULL) {
return 0;
}
return countNodes(root->left) + countNodes(root->right) + 1;
}
// 计算叶子节点数
int countLeaves(TreeNodePtr root) {
if (root == NULL) {
return 0;
} else if (root->left == NULL && root->right == NULL) {
return 1;
} else {
return countLeaves(root->left) + countLeaves(root->right);
}
}
// 计算数的深度
int countDepth(TreeNodePtr root) {
if (root == NULL) {
return 0;
}
int leftDepth = countDepth(root->left);
int rightDepth = countDepth(root->right);
return (leftDepth > rightDepth ? leftDepth : rightDepth) + 1;
}
int main() {
// 创建二叉树
TreeNodePtr root = NULL;
root = insertNode(root, 10);
root = insertNode(root, 5);
root = insertNode(root, 15);
root = insertNode(root, 3);
root = insertNode(root, 7);
root = insertNode(root, 12);
root = insertNode(root, 17);
// 输出二叉树
printf("Binary Tree:\n");
printTree(root, 0);
// 输出二叉树形状
printf("Binary Tree Shape:\n");
printShape(root, 0);
// 先序遍历并打印
printf("Preorder Traversal:\n");
preorderTraversal(root);
printf("\n");
// 层次遍历并打印
printf("Level Traversal:\n");
levelTraversal(root);
printf("\n");
// 计算节点数
printf("Node Count: %d\n", countNodes(root));
// 计算叶子节点数
printf("Leaf Count: %d\n", countLeaves(root));
// 计算数的深度
printf("Tree Depth: %d\n", countDepth(root));
return 0;
}
```
用c语言做一个用菜单函数实现的算法管理系统,该系统包含了二叉树和图的所有基础算法,包括建立与输出二叉树,输出树的形状,先序遍历二叉树并打印,层次遍历二叉树并打印,求二叉树的节点数,叶子树和深度,和用邻接矩阵建立无向图,用邻接表建立无向图,图的深度和广度优先遍历,以及用普利姆算法和库鲁斯卡尔算法实现最小生成树,求最短路径,求关键路径和输出图的形状的相关算法,这些功能都用菜单函数来实现,菜单函数分为树的子菜单和图的子菜单,用头文件和源文件的方式编写
好的,以下是一个示例代码,实现了您所描述的功能。
首先,我们需要定义二叉树和图的数据结构。这里我们使用邻接矩阵表示图。
```c
// 二叉树节点结构体
typedef struct TreeNode {
int val; // 节点值
struct TreeNode* left; // 左子节点
struct TreeNode* right; // 右子节点
} TreeNode;
// 图结构体
typedef struct Graph {
int n; // 图中节点数
int** matrix; // 邻接矩阵
} Graph;
```
接下来,我们分别实现树和图的相关算法。为了方便,这里我们只列出了函数的声明。
```c
// 树的算法
void createTree(TreeNode** root); // 建立二叉树
void printTree(TreeNode* root); // 输出二叉树
void printTreeShape(TreeNode* root); // 输出二叉树形状
void preorderTraversal(TreeNode* root); // 先序遍历并打印
void levelOrderTraversal(TreeNode* root); // 层次遍历并打印
int countNodes(TreeNode* root); // 计算节点数
int countLeaves(TreeNode* root); // 计算叶子节点数
int depth(TreeNode* root); // 计算树的深度
// 图的算法
void createGraph(Graph* graph); // 建立无向图(邻接矩阵)
void createGraphWithAdjList(Graph* graph); // 建立无向图(邻接表)
void printGraph(Graph* graph); // 输出图
void dfs(Graph* graph, int start); // 深度优先遍历
void bfs(Graph* graph, int start); // 广度优先遍历
void primMST(Graph* graph); // 普利姆算法求最小生成树
void kruskalMST(Graph* graph); // 库鲁斯卡尔算法求最小生成树
void shortestPath(Graph* graph, int start); // 求最短路径
void criticalPath(Graph* graph); // 求关键路径
```
然后,我们开始实现菜单函数。
```c
#include <stdio.h>
#include <stdlib.h>
#include "tree.h"
#include "graph.h"
int main() {
int choice;
TreeNode* root = NULL;
Graph graph;
while (1) {
printf("1. 树\n2. 图\n3. 退出\n");
printf("请选择:");
scanf("%d", &choice);
switch (choice) {
case 1:
printf("1. 建立二叉树\n");
printf("2. 输出二叉树\n");
printf("3. 输出二叉树形状\n");
printf("4. 先序遍历并打印\n");
printf("5. 层次遍历并打印\n");
printf("6. 计算节点数\n");
printf("7. 计算叶子节点数\n");
printf("8. 计算树的深度\n");
printf("9. 返回\n");
printf("请选择:");
scanf("%d", &choice);
switch (choice) {
case 1:
createTree(&root);
break;
case 2:
printTree(root);
break;
case 3:
printTreeShape(root);
break;
case 4:
preorderTraversal(root);
break;
case 5:
levelOrderTraversal(root);
break;
case 6:
printf("节点数:%d\n", countNodes(root));
break;
case 7:
printf("叶子节点数:%d\n", countLeaves(root));
break;
case 8:
printf("树的深度:%d\n", depth(root));
break;
case 9:
break;
default:
printf("无效选择\n");
break;
}
break;
case 2:
printf("1. 建立无向图(邻接矩阵)\n");
printf("2. 建立无向图(邻接表)\n");
printf("3. 输出图\n");
printf("4. 深度优先遍历\n");
printf("5. 广度优先遍历\n");
printf("6. 普利姆算法求最小生成树\n");
printf("7. 库鲁斯卡尔算法求最小生成树\n");
printf("8. 求最短路径\n");
printf("9. 求关键路径\n");
printf("10. 返回\n");
printf("请选择:");
scanf("%d", &choice);
switch (choice) {
case 1:
createGraph(&graph);
break;
case 2:
createGraphWithAdjList(&graph);
break;
case 3:
printGraph(&graph);
break;
case 4: {
int start;
printf("请输入起始节点:");
scanf("%d", &start);
dfs(&graph, start);
break;
}
case 5: {
int start;
printf("请输入起始节点:");
scanf("%d", &start);
bfs(&graph, start);
break;
}
case 6:
primMST(&graph);
break;
case 7:
kruskalMST(&graph);
break;
case 8: {
int start;
printf("请输入起始节点:");
scanf("%d", &start);
shortestPath(&graph, start);
break;
}
case 9:
criticalPath(&graph);
break;
case 10:
break;
default:
printf("无效选择\n");
break;
}
break;
case 3:
exit(0);
default:
printf("无效选择\n");
break;
}
}
return 0;
}
```
最后,我们将树和图的算法分别放在 `tree.c` 和 `graph.c` 中,并在相应头文件中声明函数。这样,我们就完成了整个算法管理系统的编写。
完整代码:
阅读全文