demo.c:
#include//树结点结构体 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掉之后,这个指针不会自动置空。
如图所示!
所以在二叉树销毁的过程中,虽然每一个结点的数据域被刷新了,但是,这个结点本身的“指针”并没有被置空。盲目的销毁二叉树可能会导致野指针的形成。
欢迎讨论、交流!



