第一次玩,水平有限,不过代码可运行
#include<stdio.h>
#include<stdlib.h>
#include<malloc.h>
typedef struct tree
{
struct tree* lchild, *rchild;
int data;
}treeNode;
treeNode* create(treeNode* ); //创建一棵树
void preordertransval(treeNode*); //前序遍历
void inordertransval(treeNode*); //中序遍历
void postordertransval(treeNode*); //后序遍历
void lookup(treeNode*); //查找树中的数字
treeNode* delete_Node(treeNode*,int); //删除树中的某一个节点
int totleNode(treeNode*); //计算二叉树中的结点
int totleLeftNode(treeNode*); //计算二叉树中的叶子结点
int totleinNode(treeNode*); //计算二叉树中的内部节点
void mirrorImage(treeNode*); //将二叉树转化为镜像
void printfMenu(); //创建一个菜单
int main()
{
treeNode* T = NULL;
int options;
printfMenu(); //打印一个菜单页面
scanf_s("%d", &options); //选择你的操作
while (options != -1)
{
if (options == 1)
{
T = create(T);
}
else if (options == 2)
{
printf("前序表达式是:\t");
preordertransval(T);
printf("\n");
}
else if (options == 3)
{
printf("中序表达式是:\t");
inordertransval(T);
printf("\n");
}
else if (options == 4)
{
printf("后序表达式是:\t");
postordertransval(T);
printf("\n");
}
else if (options == 5)
{
lookup(T);
printf("\n");
}
else if (options == 6)
{
int num;
printf("你想删除哪一个节点?\t");
scanf_s("%d", &num);
T=delete_Node(T,num);
printf("\n");
}
else if (options == 7)
{
int num;
num = totleNode(T);
printf("树中节点的个数是:%d\n", num);
}
else if (options == 8)
{
int num;
num = totleLeftNode(T);
printf("树中的叶子结点个数是:%d\n", num);
}
else if (options == 9)
{
int num;
num = totleinNode(T);
printf("树中的内部节点个数是:%d\n", num);
}
else if (options == 10)
{
mirrorImage(T);
}
else if (options == 0)
{
break;
}
printf("请再次输入你想要执行的操作:\n"); //再次选择你的操作
scanf_s("%d", &options); //选择你的操作
}
return 0;
}
treeNode* create(treeNode* T)
{
treeNode* parent_node, * ptr, * new_node;
int i; //i用来存储树中的data
printf("如果想结束请输入-1:\n");
printf("请输入二叉查找树中的数据:\t");
scanf_s("%d", &i);
while (i != -1) //输入-1树截止
{
new_node = (treeNode*)malloc(sizeof(treeNode)); //将new_node进行变量转换
new_node->data = i;
new_node->lchild = NULL;
new_node->rchild = NULL;
if (T == NULL) //创建根节点
{
T = new_node; //将根节点赋值
}
else //对树的节点进行插入
{
parent_node = NULL;
ptr = T;
while (ptr != NULL) //寻找到空的子树进行赋值
{
if (i < ptr->data)
{
parent_node = ptr;
ptr = ptr->lchild;
}
else
{
parent_node = ptr;
ptr = ptr->rchild;
}
}
if (i < parent_node->data)
{
parent_node->lchild = new_node;
}
else
{
parent_node->rchild = new_node;
}
}
printf("请再次输入二叉查找树中的数据:\t");
scanf_s("%d", &i);
}
return T;
}
void preordertransval(treeNode* T)//前序遍历二叉树
{
if (T != NULL)
{
printf("%d ", T->data);
preordertransval(T->lchild);
preordertransval(T->rchild);
}
}
void inordertransval(treeNode* T)//中序遍历
{
if (T != NULL)
{
inordertransval(T->lchild);
printf("%d ", T->data);
inordertransval(T->rchild);
}
}
void postordertransval(treeNode* T)//后序遍历二叉树,递归的思想一样,只不过遍历的时机不一样
{
if (T != NULL)
{
postordertransval(T->lchild);
postordertransval(T->rchild);
printf("%d ", T->data);
}
}
void lookup(treeNode* T)//查找二叉树中的数
{
treeNode* ptr;
ptr = T;
int i;
printf("请输入你想查找的数:\n");
scanf_s("%d", &i);
if (ptr->data == i)
printf("%d is the root number:\n", i);
else
{
while (ptr->data != i)
{
if (i < ptr->data)
{
ptr = ptr->lchild;
}
else
{
ptr = ptr->rchild;
}
if (ptr == NULL)
break;
}
if (ptr != NULL)
{
printf("树中存在%d", ptr->data);
}
else
{
printf("树中不存在该数:\n");
}
}
}
treeNode* delete_Node(treeNode* T,int i)//删除树中的某一个节点
{
treeNode* ptr,*parent_node;
parent_node = NULL;
ptr = T;
while (ptr->data != i)
{
if (i < ptr->data)
{
parent_node = ptr;
ptr = ptr->lchild;
}
else
{
parent_node = ptr;
ptr = ptr->rchild;
}
if (ptr == NULL)
break;
}
if (ptr == NULL)
printf("wrong 树中没有此数:\n");
else if (ptr->lchild == NULL && ptr->rchild == NULL)//当所要删除的节点是叶子节点时
{
if (ptr->data < parent_node->data)
parent_node->lchild = NULL;
else
parent_node->rchild = NULL;
}
else if (ptr->lchild != NULL && ptr->rchild == NULL)//ptr有左孩子没有有孩子
{
if (ptr->data < parent_node->data)
{
parent_node->lchild = ptr->lchild;
free(ptr);
}
else
{
parent_node->rchild = ptr->lchild;
free(ptr);
}
}
else if (ptr->lchild == NULL && ptr->rchild != NULL)//ptr有右孩子没有左孩子
{
if (ptr->data < parent_node->data)
{
parent_node->lchild = ptr->rchild;
free(ptr);
}
else
{
parent_node->rchild = ptr->rchild;
}
}
else if (ptr->lchild != NULL && ptr->rchild != NULL)//用中序遍历的前一个数或者后一个数来代替被删除的数
{
treeNode* find,*find_parent;//这个数是用来寻找中序遍历的前一个数的(后一个数方法一样,在这里我们不做展示)
find = T;
find_parent = NULL;
inordertransval(T);
int t;
printf("%d前面的数是:", i);
scanf_s("%d", &t);
while (find->data != t)
{
if (t < find->data)
{
find_parent = find;
find = find->lchild;
}
else
{
find_parent = find;
find = find->rchild;
}
if (find == NULL)
break;
}
int n;//n存放find中的数;
n = find->data;
if (find->data < find_parent->data) //如果提前赋值将导致find和find_parent中的数相等从而使右子树全部被删除
find_parent->lchild = NULL;
else
find_parent->rchild = NULL;
ptr->data = n;//将find删除之后,再将find中的数赋值给ptr
}
return T;
}
int totleNode(treeNode* T)
{
if (T == NULL)
return 0;
else
return(totleNode(T->lchild) + totleNode(T->rchild) + 1);//每遍历一个节点就加一,知道遍历结束
}
int totleLeftNode(treeNode* T)
{
if (T == NULL)
return 0;
else if ((T->lchild == NULL) && (T->rchild == NULL))
return 1;
else
return(totleLeftNode(T->lchild) + totleLeftNode(T->rchild));
}
int totleinNode(treeNode* T)
{
if (T == NULL || ((T->rchild == NULL) && (T->rchild == NULL)))
return 0;
else
return(totleinNode(T->lchild) + totleinNode(T->rchild) + 1);
}
void mirrorImage(treeNode* T)
{
if (T!=NULL)
{
treeNode* ptr;
ptr = T->rchild;
T->rchild = T->lchild;
T->lchild = ptr;
mirrorImage(T->lchild);
mirrorImage(T->rchild);
}
}
void printfMenu()
{
printf("开始-------------------\n");
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("0》退出\n");
printf("-----------------------\n");
}