二叉树的建立与排序

一、树的定义:

1、定义:树(Tree)是n(n>=0)个节点的有限集,n=0时称为“空树”。在任意一棵非空树中:

⒈有且仅有一个特定的称为根(root)的节点。

⒉当n>1时,其余节点可分为m(m>0)个互不相交的有限集T1、T2……Tm,其中每一个集合本身又是一棵树,并且称之为根的子树(SubTree)。

2、树的节点的分类:

树的节点包含一个数据元素以及若干个指向其子树的分支。节点拥有的子树个数称为节点的度(Degree)。度为0的节点称为叶节点(Leaf);度不为0且不为根节点的节点称为“内部节点”。

3、节点间关系:

节点的子树的根称为该节点的孩子(Child),相应地,该节点称为孩子的父(Parent,或翻译成“双亲”)。同一个父节点的孩子之间互称兄弟(Sibling)。

4、层次:

节点的层次(Level)从根开始定义起,根为第一层,根的孩子为第二层,依次类推。树中节点的最大层次称为树的深度(Depth)或高度。

如果该树中节点的子树看成是从左到右有次序的,不能互换的,则称该树为有序树,否则称为无序树。

二、二叉树概念

1、定义:二叉树(BinaryTree)是n(n>=0)个节点的有限集合,该集合或者为空集(称为“空二叉树”),或者由一个根节点和两棵互不相交的、分别称为根节点的左子树和右子树的二叉树组成。

定理:任意一棵树都可以完全等价于一棵二叉树。

2、二叉树的特点:

1)每个节点最多有两棵子树,所以二叉树中不存在度大于2的节点。

2)左子树和右子树有序,不能随意颠倒。

3)即使树中某节点只有一棵子树,也要区分它是左子树还是右子树,不能混淆。

3、满二叉树:

在一棵二叉树中,如果所有分支节点都存在左子树和右子树,并且所有叶子节点都在同一层上,这样的二叉树称为满二叉树。

满二叉树的特点有:

1)叶子节点只能出现在最下面一层。出现在其他层就不可能达到平衡。

2)非叶子节点的度一定是2。

3)在同样深度的二叉树中,满二叉树的节点个数最多,叶子节点个数最多。

4、完全二叉树:

对一棵具有n个节点的二叉树按层序编号,如果编号为i(1<=i<=n)的节点与同样深度的满二叉树中编号为i的节点在二叉树中的位置完全相同,则这棵二叉树称为完全二叉树。

二、二叉树的性质

1、性质1:在二叉树的第i层上至多有2^(i-1)个节点(i>=1)。

2、性质2:深度为k的二叉树至多有2^k-1个节点(k>=1)。注意不是2^(k-1)。

3、性质3:对于任何一棵二叉树T,如果其叶子节点数为n0,度为2的节点数为n2,则n0=n2+1。

性质3的推导:

二叉树的节点的度只有3种:0、1、2。我们设其对应的节点数分别为n0、n1、n2,则二叉树的节点总数为:

Tn=n0+n1+n2

二叉树的连线数应等于节点个数减1,即

Sn=Tn-1

另一方面,二叉树的连线数应等于2*n2+n1,即

Sn=2*n2+n1

我们可得到:

n0+n1+n2-1=2*n2+n1

整理可得

n0=n2+1

三、二叉树链式存储

二叉树每个节点最多有两个孩子,所以为它涉及一个数据域和两个指针域。

lchild︱data︱rchild

其中data是数据域,lchild和rchild都是指针域,分别存放指向左孩子和右孩子的指针。

typedef struct BiTNode

{

       data_tdata;

       structBiTNode *lchild,*rchild;

}BiTNode,*BiTree;

四、二叉树的遍历

二叉树的遍历(traversing)是指从根节点出发,按照某种次序依次访问二叉树中所有节点,使得每个节点被且仅被访问一次。

二叉树的遍历方式有很多,常用的有前序遍历、中序遍历、后序遍历3种。

1、前序遍历(PreOrderTraverse)

规则:

⒈若二叉树为空,则不进行操作,返回

⒉访问根节点

⒊前序遍历左子树

⒋前序遍历右子树

2、中序遍历(InOrderTraverse)

规则:

⒈若二叉树为空,则不进行操作,返回

⒉中序遍历左子树

⒊访问根节点

⒋中序遍历右子树

3、后序遍历(PostOrderTraverse)

规则:

⒈若二叉树为空,则不进行操作,返回

⒉后序遍历左子树

⒊后序遍历右子树

⒋访问根节点

/*************************************************************************

 @Author: wanghao

 @Created Time : Fri 11 May 2018 12:54:47 AMPDT

 @File Name: tree.c

 @Description:

 ************************************************************************/

#include <stdio.h>

#include <stdlib.h>

typedef char data_t;

typedef struct tree

{

       data_tdata;

       structtree *lchild;

       structtree *rchild;

}Tree;

Tree *init_tree(void)

{

       Tree*treenode = NULL;

       treenode= (Tree *)malloc(sizeof(Tree));

       if(treenode== NULL)

       {

              printf("Malloctree fail!\n");

              returnNULL;

       }

       treenode->lchild= NULL;

       treenode->rchild= NULL;

       treenode->data= 0;

       returntreenode;

}

Tree *bulid_tree(data_t data[], int i, intn)

{

       intj;

       Tree*tree = NULL;

       tree= init_tree();

       if(!tree)

       {

              printf("Inittree fail!\n");

              returnNULL;

       }

      

       tree->data= data[i];

       j= 2*i;

       if(j<= n && data[j] != '0')

       {

              tree->lchild= bulid_tree(data, j, n);

       }

       else

       {

              tree->lchild= NULL;

       }

       j= 2*i + 1;

       if(j<= n && data[j] != '0')

       {

              tree->rchild= bulid_tree(data, j, n);

       }

       else

       {

              tree->rchild= NULL;

       }

      

       returntree;

}

int pre_order_traverse(Tree *root)

{

       if(root== NULL)

       {

              printf("Binarytree is not exist!\n");

              return-1;

       }

       printf("%c\t",root->data);

       if(root->lchild)

       {

              pre_order_traverse(root->lchild);

       }

       if(root->rchild)

       {

              pre_order_traverse(root->rchild);

       }

}

int in_order_traverse(Tree *root)

{

       if(root== NULL)

       {

              printf("Binarytree is not exist!\n");

              return-1;

       }

       if(root->lchild)

       {

              in_order_traverse(root->lchild);

       }

      

       printf("%c\t",root->data);

       if(root->rchild)

       {

              in_order_traverse(root->rchild);

       }

}

int post_order_traverse(Tree *root)

{

       if(root== NULL)

       {

              printf("Binarytree is not exist!\n");

              return-1;

       }

       if(root->lchild)

       {

              post_order_traverse(root->lchild);

       }

       if(root->rchild)

       {

              post_order_traverse(root->rchild);

       }

       printf("%c\t",root->data);

}

int main(int argc, const char *argv[])

{

       Tree*root;

       data_tarray[] = {0,

                    'A',

                    'B',        'C',

                    'D','E',    0, 'F',

                    0,0,'G','H',0,0,'I'

                    };

       root= bulid_tree(array, 1, sizeof(array) / sizeof(data_t));

       pre_order_traverse(root);

       printf("\n");

       in_order_traverse(root);

       printf("\n");

       post_order_traverse(root);

       printf("\n");

       return0;

}


猜你喜欢

转载自blog.csdn.net/weixin_42048417/article/details/80327319