本篇博客记录二叉树的基本操作,无聊的时候打发时间写的,防止时间长了不写写就忘没了(づ ●─● )づ
demo.c:
#include <stdio.h>
//树结点结构体
typedef struct BiTNode
{
char data;
struct BiTNode* lchild, * rchild;
}BiTree;
//初始化二叉树
BiTree* InitTree(void)
{
BiTree* root = (BiTree*)malloc(sizeof(BiTree));
root->lchild = NULL;
root->rchild = NULL;
return root;
}
//后序销毁二叉树
void ClearBree(BiTree* p)
{
if (p != NULL)
{
ClearBree(p->lchild);
ClearBree(p->rchild);
free(p);
}
}
//前序建立二叉树
void CreateTree(BiTree* p)
{
char c;
c = getch();
printf("%c", c);
if (c != '#')
{
p->data = c;
p->lchild = (BiTree*)malloc(sizeof(BiTree));
p->rchild = (BiTree*)malloc(sizeof(BiTree));
CreateTree(p->lchild);
CreateTree(p->rchild);
}
else
{
p->data = c;
p->lchild = NULL;
p->rchild = NULL;
return;
}
}
//前序遍历
void PreOrderTraverse(BiTree* p)
{
if (p != NULL && p->data != '#')
{
printf("%c", p->data);
PreOrderTraverse(p->lchild);
PreOrderTraverse(p->rchild);
}
}
//中序遍历
void InOrderTraverse(BiTree* p)
{
if (p != NULL && p->data != '#')
{
InOrderTraverse(p->lchild);
printf("%c", p->data);
InOrderTraverse(p->rchild);
}
}
//后序遍历
void PostOrderTraverse(BiTree* p)
{
if (p != NULL && p->data != '#')
{
PostOrderTraverse(p->lchild);
PostOrderTraverse(p->rchild);
printf("%c", p->data);
}
}
int main()
{
int judge;
BiTree* root;
while (1)
{
fflush(stdin);
printf("1.初始化二叉树\n2.销毁二叉树\n3.创建二叉树(#)\n4.前序遍历\n5.中序遍历\n6.后序遍历\n");
scanf("%d", &judge);
switch (judge)
{
case 1://初始化二叉树
root = InitTree();
break;
case 2://销毁二叉树
ClearBree(root);
if (root->lchild == NULL || root->rchild == NULL)
{
printf("ha");
}
break;
case 3://创建二叉树
CreateTree(root);
printf("\n");
break;
case 4://前序遍历
PreOrderTraverse(root);
printf("\n");
break;
case 5://中序遍历
InOrderTraverse(root);
printf("\n");
break;
case 6://后序遍历
PostOrderTraverse(root);
printf("\n");
break;
default:
printf("请输入正确的数字!!!\n");
}
}
return 0;
}
注:关于动态空间分配,在一个结构体指针指向的空间被free掉之后,这个指针不会自动置空。
如图所示!
所以在二叉树销毁的过程中,虽然每一个结点的数据域被刷新了,但是,这个结点本身的“指针”并没有被置空。盲目的销毁二叉树可能会导致野指针的形成。
欢迎讨论、交流!