用c语言做一个用菜单函数实现的算法管理系统,该系统包含了二叉树和图的所有基础算法,包括建立与输出二叉树,输出树的形状,先序遍历二叉树并打印,层次遍历二叉树并打印,求二叉树的节点数,叶子树和深度,和用邻接矩阵建立无向图,用邻接表建立无向图,图的深度和广度优先遍历,以及用普利姆算法和库鲁斯卡尔算法实现最小生成树,求最短路径,求关键路径和输出图的形状的相关算法,这些功能都用菜单函数来实现,菜单函数分为树的子菜单和图的子菜单,用头文件和源文件的方式编写
时间: 2023-09-18 08:15:46 浏览: 118
好的,以下是一个示例代码,实现了您所描述的功能。
首先,我们需要定义二叉树和图的数据结构。这里我们使用邻接矩阵表示图。
```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` 中,并在相应头文件中声明函数。这样,我们就完成了整个算法管理系统的编写。
完整代码:
阅读全文