二叉树对我们来说已经不陌生了,这是一个非常常用的数据结构,常见的二叉树的应用:二叉排序树、二叉平衡树、红黑树、二叉堆等等,这些都是关于二叉树的一些数据结构;好了我们废话少说,下面我们一起来了解一些二叉树。
二叉树的一些基本术语和特性
二叉树是每个节点最多有两个子树的树结构。通常子树被称作“左子树”(left subtree)和“右子树”(right subtree)。
二叉树的每个结点至多只有二棵子树(不存在度大于2的结点),二叉树的子树有左右之分,次序不能颠倒。二叉树的第i层至多有个结点;深度为k的二叉树至多有个结点;对任何一棵二叉树T,如果其终端结点数为,度为2的结点数为,则。
满二叉树:一棵深度为k,且有(2的k次方)-1个节点成为满二叉树。
完全二叉树:深度为k,有n个节点的二叉树,当且仅当其每一个节点都与深度为k的满二叉树中序号为1至n的节点对应时,称之为完全二叉树。
二叉树的存储结构:
顺序存储表示
二叉树可以用数组或线性表来存储,而且如果这是完全二叉树,这种方法不会浪费空间。用这种紧凑排列,如果一个结点的索引为i,它的子结点能在索引2i+1和2i+2找到,并且它的父节点(如果有)能在索引floor((i-1)/2)找到(假设根节点的索引为0)。这种方法更有利于紧凑存储和更好的访问的局部性,特别是在前序遍历中。然而,它需要连续的存储空间,这样在存储高度为h的n个结点组成的一般普通树时将会浪费很多空间。一种最极坏的情况下如果深度为h的二叉树每个节点只有右孩子需要占用2的h次幂减1,而实际却只有h个结点,空间的浪费太大,这是顺序存储结构的一大缺点。
二叉链表存储表示
在使用记录或内存地址指针的编程语言中,二叉树通常用树结点结构来存储。有时也包含指向唯一的父节点的指针。如果一个结点的子结点个数小于2,一些子结点指针可能为空值,或者为特殊的哨兵结点。 使用链表能避免顺序储存浪费空间的问题,算法和结构相对简单,但使用二叉链表,由于缺乏父链的指引,在找回父节点时需要重新扫描树得知父节点的节点地址。
typedef struct BiTNode { TElemType data; struct BiTNode *lchild,*rchild; /* 左右孩子指针 */ }BiTNode,*BiTree;
二叉树的基本操作
/* 按先序次序输入二叉树节点的值(可为字符型或整型,在主程中定义),*/
/* 构造二叉链表表示的二叉树T。变量Nil表示空(子)树。 */
void CreateBiTree(BiTree &T)
{
TElemType ch;
scanf(form, ch);
if(ch == Nil) /* 空 */
T = NULL;
else
{
T = new BiTNode; /* 生成根结点*/
if(NULL == T)
exit(OVERFLOW);
T->data=ch;
CreateBiTree(T->lchild); /* 构造左子树*/
CreateBiTree(T->rchild); /* 构造右子树*/
}
}
/*二叉树的先、中、后序遍历*/
void preOrder(BiTree root)
{
if( root != NULL)
{
cout << root->data << ' ';
preOrder(root->lchild);
preOrder(root->rchild);
}
}
void inOrder(BiTree root)
{
if( root != NULL)
{
preOrder(root->lchild);
cout << root->data << ' ';
preOrder(root->rchild);
}
}
void postOrder(BiTree root)
{
if( root != NULL)
{
preOrder(root->lchild);
preOrder(root->rchild);
cout << root->data << ' ';
}
}
/*求二叉树的深度*/
int getDepth(BiTree root)
{
int deplef = 0;
int deprig = 0;
int deptal = 0;
if(root == NULL) return 0;
deplef = getDepth(root->lchild) + 1;
deprig = getDepth(root->rchild) + 1;
deptal = deplef > deprig ? deplef:deprig;
return deptal;
}
/*求二叉树的叶子结点个数*/
int CountTreeLeaf(BiTree root)
{
if(root == NULL)
return 0;
else if(root->lchild == NULL && root->rchild == NULL)
return 1;
else
return CountTreeLeaf(root->lchild)+CountTreeLeaf(root->rchild);
}
待续。。。。。