树的概念:
结点:
树的结点包含一个数据元素及若干个指向其子树的分支。
度:
结点拥有的子树称为结点的度。
叶结点:
度为0的结点称为叶结点或者终端结点。
分支结点:
度不为0的结点称为非终端结点或者分支结点。
孩子、双亲:
结点的子树的跟称为该结点的孩子,相应的,该结点称为孩子的双亲。
深度:
树中结点最大层次称为树的深度。
二叉树的特点 :
每个结点最多有两棵子树,所以二叉树中不存在度大于2的结点。
左子树和右子树是有顺序的,次序不能任意颠倒。 即使树中某结点只有一棵子树,也要区分它是左子树还是右子树。
二叉树的性质:
性质1 :
在二叉树的第i层上至多有 2 ^ (i - 1)个结点 。
性质2 :
深度为k的二叉树至多有 2 ^ k - 1个结点 。
性质3 : 对任何一棵二叉树T,如果其终端结点数为n,度为2的结点数为m,则n=m+1。
性质4 具有n个结点的完全二叉树的深度为 log2(n + 1)。
性质5 如果对1棵有n个结点的二叉树的结点按层序编号,对任一结点i:
如果i=1,则结点i是二叉树的根,无双亲,如果i>1,则其双亲是结点 i / 2。
如果2i>n,则结点i无左孩子,否则,其左孩子是2i 。
如果2i+1>n,则结点i无右孩子;否则其右孩子是结点2i+1。
代码:
struct nodetree//定义一个结构体来存放结点信息
{
int data;
struct nodetree *right;
struct nodetree *left;
};
typedef struct nodetree Tree;
Tree *create(int *a)//创建一个树
{
int i;
Tree *Node[11] = {0};//定义一个长度为11的指针数组存放结点结构体的地址(数组长度大于结点数,为连接双亲和孩子做准备)
for(i = 0;i < 10;i++)
{
Node[i] = (Tree *) malloc (sizeof(Tree));//分配空间
if(NULL == Node[i])
{
printf("inti false\n");
}
Node[i]->data = a[i];//初始化结点结构体中的变量
Node[i]->right = NULL;
Node[i]->left = NULL;
}
for(i = 0;i < 10 / 2;i++)//连接双亲和孩子
{
Node[i]->left = Node[2 * i + 1];
Node[i]->right = Node[2 * i + 2];
}
return Node[0];//返回根结点地址
}
int preorder (Tree *q)//先序遍历(双亲、左孩子、右孩子)
{
if(q == NULL)
{
return 1;
}
printf("%d ",q->data);
preorder(q->left);
preorder(q->right);
return 0;
}
int inorder(Tree *q)//中序遍历(左孩子、双亲、右孩子)
{
if(q == NULL)
{
return 1;
}
inorder(q->left);
printf("%d ",q->data);
inorder(q->right);
return 0;
}
int postorder(Tree *q)//后序遍历(左孩子、右孩子、双亲)
{
if(q == NULL)
{
return 1;
}
postorder(q->left);
postorder(q->right);
printf("%d ",q->data);
return 0;
}