树是一个由n个有限节点组成并具有层次关系的集合,是一种非线性的数据结构。树是由跟节点和它的子树构成,所以树的定义是递归的。二叉树是树的一种,它的特点是至多有两颗字树,并且二叉树的子树也有左右之分,不能互相颠倒。
二叉树常用的遍历方式有三种,即:前序遍历,中序遍历,后序遍历,这三遍历方式的主要却别是访问根结点和遍历左子树、右子树的先后关系不一样。
访问顺序:
前序遍历:根->左->右
中序遍历:左->根->右
后序遍历:左->右->根
下面由树的递归建立和对树进行递归遍历:树的实现借助链表,而链表的节点正是树的结点,包含着一二数据域,指针域中包括分别指向左孩子和右孩子的指针
//定义节点
typedef struct Node
{
int data;
struct Node* rchild;
struct Node* lchild;
}Node;//递归建立树
//建树
Node* create_tree()
{
int _data;
scanf("%d",&_data);
if(_data==-1)
{
return NULL;
}
Node* root=(Node*)malloc(1*sizeof(Node));
root->data=_data;
root->lchild=create_tree();
root->rchild=create_tree();
return root;
}//前序遍历: 根->左->右
//递归前序遍历
void qian_print(Node* root)
{
if(root!=NULL)
{
printf("%d\t",root->data);
qian_print(root->lchild);
qian_print(root->rchild);
}
}中序遍历:左->根->右
//递归中序遍历
void zhong_print(Node* root)
{
if(root!=NULL)
{
zhong_print(root->lchild);
printf("%d\t",root->data);
zhong_print(root->rchild);
}
}后序遍历:左->右->根
//递归后序遍历
void hou_print(Node* root)
{
if(root!=NULL)
{
hou_print(root->lchild);
hou_print(root->rchild);
printf("%d\t",root->data);
}
}最后实现三个小练习
1.求叶子的节点数(左子树为空,右子树也为空)
void count_leaf(Node* root,int* count)
{
if(root!=NULL)
{
if(root->lchild==NULL && root->rchild==NULL)
{
(*count)++;
}
count_leaf(root->lchild,count);
count_leaf(root->rchild,count);
}
}2.求树的深度
int deth(Node* root)
{
int dethval=0,dethl=0,dethr=0;
if(root==NULL)
{
return 0;
}
dethl=deth(root->lchild);
dethr=deth(root->rchild);
dethval=1+(dethl>dethr?dethl:dethr);
return dethval;
}
3.copy二叉树
Node* copy_tree(Node* root)
{
Node* newnode,*newrptr,*newlptr;
if(root==NULL)
{
return NULL;
}
if(root->lchild!=NULL)
{
newlptr=copy_tree(root->lchild);
}
else
{
newlptr=NULL;
}
if(root->rchild!=NULL)
{
newrptr=copy_tree(root->rchild);
}
else
{
newrptr=NULL;
}
newnode=(Node*)malloc(1*sizeof(Node));
newnode->lchild=newlptr;
newnode->rchild=newrptr;
newnode->data=root->data;
return newnode;
}本文出自 “君峰俊宇” 博客,请务必保留此出处http://10274409.blog.51cto.com/10264409/1746519
原文:http://10274409.blog.51cto.com/10264409/1746519