在计算机科学中,二叉树是每个节点最多有两个子树的树结构。通常子树被称作“左子树”(left subtree)和“右子树”(right subtree)。二叉树常被用于实现二叉查找树和二叉堆。
二叉树的每个结点至多只有二棵子树(不存在度大于2的结点),二叉树的子树有左右之分,次序不能颠倒。二叉树的第i层至多有2^{i-1}个结点;深度为k的二叉树至多有2^k-1个结点;对任何一棵二叉树T,如果其终端结点数为n_0,度为2的结点数为n_2,则n_0=n_2+1。
一棵深度为k,且有2^k-1个节点的二叉树,称为满二叉树。这种树的特点是每一层上的节点数都是最大节点数。而在一棵二叉树中,除最后一层外,若其余层都是满的,并且最后一层或者是满的,或者是在右边缺少连续若干节点,则此二叉树为完全二叉树。具有n个节点的完全二叉树的深度为log2n+1。深度为k的完全二叉树,至少有2^(k-1)个节点,至多有2^k-1个节点
二叉树性质
(1) 在非空二叉树中,第i层的结点总数不超过 2^(i-1) , i>=1;
(2) 深度为h的二叉树最多有 2^(h-1) 个结点(h>=1),最少有h个结点;
(3) 对于任意一棵二叉树,如果其叶结点数为N0,而度数为2的结点总数为N2,则N0=N2+1;
(4) 具有n个结点的完全二叉树的深度为 log2(n+1)
(5)有N个结点的完全二叉树各结点如果用顺序方式存储,则结点之间有如下关系:
若I为结点编号则 如果I>1,则其父结点的编号为【i/2】
如果2*I<=N,则其左儿子(即左子树的根结点)的编号为2*I;若2*I>N,则无左儿子;
如果2*I+1<=N,则其右儿子的结点编号为2*I+1;若2*I+1>N,则无右儿子。
树的定义:
struct treenode
{
int data; //数据
struct treenode *left, *right; //左右孩子
};
typedef struct treenode TreeNode;
树的初始化:
int array[10]={1,2,3,4,5,6,7,8,9,10};
TreeNode *Root;
Root = CreatTree(array,sizeof(array)/sizeof(array[0]));
TreeNode* CreatTree(int array[], int length)
{
TreeNode *a[11]={0};
int i;
for(i=0; i<length; i++)
{
a[i]=(TreeNode*)malloc(sizeof(TreeNode));
if(a[i]==NULL)
{
return NULL;
}
a[i]->data=array[i];
a[i]->left=a[i]->right=NULL;
}
for(i=0; i<length/2; i++)
{
a[i]->left=a[2*i+1];
a[i]->right=a[2*i+2];
}
return a[0];
}
树的遍历:
前序遍历:
void PreOrderTree(TreeNode* root)
{
if(NULL==root)
{
return;
}
printf("%d ",root->data);
PreOrderTree(root->left);
PreOrderTree(root->right);
}
中序遍历:
void InOrderTree(TreeNode* root)
{
if(NULL==root)
{
return;
}
InOrderTree(root->left);
printf("%d ",root->data);
InOrderTree(root->right);
}
后序遍历:
void ForOrderTree(TreeNode* root)
{
if(NULL==root)
{
return;
}
ForOrderTree(root->left);
ForOrderTree(root->right);
printf("%d ",root->data);
}