本文主要讲述有序二叉树的创建、插入、遍历、销毁,大体思路如下:
1、定义一个整型数组arr,存放10个乱序排放的数字
2、创建一个二叉树,存放arr中的元素。
①创建树的跟结点,将arr[0]作为根节点的数据
②利用左小右大的思想,插入数组arr中的剩余数据
3、遍历树
①中序遍历
②先序遍历
③后序遍历
4、销毁树
使用make工程进行编写,头文件、主函数、子函数代码如下:
1、头文件
#ifndef _TREE_H
#define _TREE_H
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
//定义元素的数据类型
typedef int data_type;
//定义树中结点的数据类型
typedef struct treeNode
{
struct treeNode *lChild;
data_type data;
struct treeNode *rChild;
}Tree;
enum res
{
TREENULL = -1,
OK
};
//创建树的根结点
Tree *createTree(data_type item);
//插入数据(左小右大)
int insertTree(Tree *pBoot, data_type item);
//遍历树(中序遍历)
void midOrder(Tree *pBoot);
//先序遍历
void preOrder(Tree *pBoot);
//后序遍历
void postOrder(Tree *pBoot);
//销毁树空间
int destroyTree(Tree **pBoot);
#endif
2、主函数
#include "../include/tree.h"
int main(void)
{
data_type arr[10] = {23,42,45,12,2,54,24,34,13,9};
int op = 0;
int i = 0;
Tree *pTree = NULL;
pTree = createTree(arr[0]);
while(1)
{
printf("***系统操作***\n");
printf("1-----------------insertTree\n");
printf("2-----------------midOrder\n");
printf("3-----------------preOrder\n");
printf("4-----------------postOrder\n");
printf("5-----------------contrarylink\n");
printf("0-----------------quit\n");
printf("hello,please input:");
scanf("%d",&op);
if(0 == op) break;
switch(op)
{
case 1:
{
//printf("请输入10个数据进行插入:");
for(i = 0; i < 10; i++)
{
//scanf("%d", &arr[i]);
insertTree(pTree, arr[i]);
}
break;
}
case 2:
{
printf("中序遍历结果为:");
midOrder(pTree);
printf("\n");
break;
}
case 3:
{
printf("先序遍历结果为:");
preOrder(pTree);
printf("\n");
break;
}
case 4:
{
printf("后序遍历结果为:");
postOrder(pTree);
printf("\n");
break;
}
case 5:
{
printf("释放前地址:%p\n", pTree);
destroyTree(&pTree);
printf("释放后地址:%p\n", pTree);
break;
}
default:
printf("输入不合法,请重新输入!\n");
}
}
return OK;
}
3、子函数
#include "../include/tree.h"
//子函数:创建树的根结点
Tree *createTree(data_type item)
{
Tree *pBoot = (Tree *)malloc(sizeof(Tree));
if(NULL == pBoot)
{
perror("malloc error");
return NULL;
}
memset(pBoot, 0 ,sizeof(Tree));
pBoot->data = item;
return pBoot;
}
//子函数:插入数据(根据左小右大思想插入)
int insertTree(Tree *pBoot, data_type item)
{
if(NULL == pBoot)
{
return TREENULL;
}
//创建新结点
Tree *pNew = createTree(item);
while(1)
{
//如果插入的数据小于根数据,则插入左子树
if(pNew->data < pBoot->data)
{
//如果左子树不为空,则指向下一个左子树
if(pBoot->lChild != NULL)
{
pBoot = pBoot->lChild;
}
//如果左子树为空,则进行插入
else
{
pBoot->lChild = pNew;
return OK;
}
}
//如果插入的数据小于根数据,则插入右子树
else
{
//如果右子树不为空,则指向下一个右子树
if(pBoot->rChild != NULL)
{
pBoot = pBoot->rChild;
}
//如果右子树为空,则进行插入
else
{
pBoot->rChild = pNew;
return OK;
}
}
}
}
//子函数:遍历树(中序遍历)
void midOrder(Tree *pBoot)
{
if(NULL == pBoot)
{
return;
}
midOrder(pBoot->lChild);
printf("%d ", pBoot->data);
midOrder(pBoot->rChild);
}
//子函数:先序遍历
void preOrder(Tree *pBoot)
{
if(NULL == pBoot)
{
return;
}
printf("%d ", pBoot->data);
preOrder(pBoot->lChild);
preOrder(pBoot->rChild);
}
//子函数:后序遍历
void postOrder(Tree *pBoot)
{
if(NULL == pBoot)
{
return;
}
postOrder(pBoot->lChild);
postOrder(pBoot->rChild);
printf("%d ", pBoot->data);
}
//子函数:销毁空间
int destroyTree(Tree **pBoot)
{
if(NULL == *pBoot)
{
return -1;
}
destroyTree(&((*pBoot)->lChild));
destroyTree(&((*pBoot)->rChild));
printf("销毁前地址:%p\n", *pBoot);
free(*pBoot);
*pBoot = NULL;
printf("销毁后地址:%p\n", *pBoot);
return OK;
}
运行结果如下图: