一.二叉树的结构和性质
二叉树是由许多个节点组成的一种树状的存储数据的结构,每个节点包含了存储的数据和左右两个分支的指针以及一个记录访问该节点次数的计数器。
每个节点的左子节点的数据小于该节点,该节点小于右子节点。
根据以上二叉树的性质,我们在创建二叉树时可以有一下迭代关系式:
创建节点和添加数据:
creatnode(value)
addnode(struct node *proot,int value)=
- proot (proot->item = value)
- proot->pleft=creatnode() (proot->pleft==NULL)
addnode(proot->pleft,value) (proot->item>value) - proot->pright=creatnode() (proot->prigh==NULL)
addnode(proot->pright,value) (proot->item<value)
根据以上迭代关系式可以写出如下代码:
#include<stdlib.h>
#include<stdio.h>
#include<ctype.h>
struct node //二叉树的节点定义
{
int item;
int count;
struct node *pleft;
struct node *pright;
};
struct node * creatnode(int value) //开辟动态内存(为节点开辟空间)放置节点数据(赋值)同时定义左节点和右节点
{
struct node *pnode=(struct node *)malloc(sizeof(struct node));
pnode->item=value;
pnode->count=1;
pnode->pleft=pnode->pright=NULL;
return pnode;
}
struct node * addnode(struct node *pnode,int value)//根据二叉树的根节点(显然是要查询的那个二叉树)和数值(需要查询的那个数)将二叉树中具有相同数值的那个节点的地址返回
{
if (pnode==NULL) //如果调用本函数的根节点地址为零,则说明该二叉树不存在,需要重新创建一个
{
return creatnode(value);
}
if (value==pnode->item) //如果该节点的数据和查询的数据数值相等,则该节点就是要查询的节点,返回该节点的地址
{
++pnode->count;
return pnode;
}
if (value<pnode->item) //如果要查询的数据小于该节点则查询该节点的左子节点
{
if (pnode->pleft==NULL) //如果该节点没有左子节点,则创建该节点的左子节点,并将查询的数据复制给该节点
{
pnode->pleft = creatnode(value);
return pnode->pleft;
}
else{ //该节点有左子节点,则迭代查询该左子节点
return addnode(pnode->pleft,value);
}
}
else //如果要查询的数据小于该节点则查询该节点的右子节点
{
if (pnode->pright==NULL) //如果该节点没有右子节点,则创建该节点的右子节点,并将查询的数据复制给该节点
{
pnode->pright = creatnode(value);
return pnode->pright;
}
else{
return addnode(pnode->pright,value);
}
}
}
void listnode(struct node * pnode) //以升序的方式迭代遍历该根节点二叉树的整个数据
{
if (pnode->pleft!=NULL) //按顺序从左到右,先遍历左子节点,再打印本节点,最后遍历右子节点,然后就迭代回上一节点,在循环同一步骤,直到根节点为止。
{
listnode(pnode->pleft);
}
for (int i = 0; i < pnode->count; i++)
{
printf("%d\n",pnode->item);
}
if (pnode->pright!=NULL)
{
listnode(pnode->pright);
}
}
int main(int argc, char const *argv[])
{
struct node *proot; //创建一个根节点的地址
proot = NULL;
int value=0; //要查询或者添加到节点上的数据
char test='\0'; //yes or no
do{
printf("enter the node value:\n");
scanf("%d",&value);
getchar();
if (proot==NULL) //刚开始根节点没有创建,需要创建
{
proot=creatnode(value); //将创键的根节点地址给指针
}
else
{
addnode(proot,value); //将键盘上输入的数据添加在根节点上创建的二叉树上,或者查询二叉树上已有的数据
}
printf("Do you want to enter anther:Y/N");
scanf("%c",&test);
getchar();
}while(test!='n');
printf("开始升序排列\n");
listnode(proot);
return 0;
}