二叉树的二叉链表表示与实现

来源:互联网 发布:网站名称与域名 编辑:程序博客网 时间:2024/04/28 07:39
二叉树的特点是每个结点至多只有两棵子树,且二叉树有左右字子树之分,次序不能任意颠倒。

二叉树的存储结构可以用顺序存储和链式存储来存储。二叉树的顺序存储结构由一组连续的存储单元依次从上到下,从左到右存储完全二叉树的结点元素。对于一般二叉树,应将其与完全二叉树对应,然后给每个结点从1到i编上号,依次存储在大小为i-1的数组中。这种方法只适用于完全二叉树,对非完全二叉树会浪费较多空间,最坏情况一个深度为k的二叉树只有k个结点,却需要长度为2的k次方减一长度的一位数组。事实上,二叉树一般使用链式存储结构,由二叉树的定义可知,二叉树的结点由一个数据元素和分别指向其左右孩子的指针构成,即二叉树的链表结点中包含3个域,这种结点结构的二叉树存储结构称之为二叉链表。

  • 二叉链表的存储结构
[cpp] view plaincopy
  1. typedef struct tnode {  
  2.     elemtype        data;  
  3.     struct tnode        *lchild;  
  4.     struct tnode        *rchild;  
  5. }*bitree, bitnode;  
  • 创建一棵二叉树(按先序序列建立)
[cpp] view plaincopy
  1. int create_bitree(bitree *bt)  
  2. {  
  3.     elemtype    data;  
  4.   
  5.     scanf("%d", &data);  
  6.     if (0 == data) {  
  7.         *bt = NULL;  
  8.     } else {  
  9.         *bt = (bitree)malloc(sizeof(bitnode));  
  10.         if (!(*bt))  
  11.             exit(OVERFLOW);  
  12.         (*bt)->data = data;  
  13.         create_bitree(&(*bt)->lchild);  
  14.         create_bitree(&(*bt)->rchild);  
  15.     }  
  16.     return OK;  
  17. }  
按先序次序输入二叉树的结点值,0表示空树。
  • 二叉树的遍历(先序、中序、后序)
[cpp] view plaincopy
  1. void preorder(bitree bt, int (*visit)(elemtype e))  
  2. {  
  3.     if (bt) {  
  4.         visit(bt->data);  
  5.         preorder(bt->lchild, visit);  
  6.         preorder(bt->rchild, visit);  
  7.     }  
  8. }  
[cpp] view plaincopy
  1. void inorder(bitree bt, int (*visit)(elemtype e))  
  2. {  
  3.     if (bt) {  
  4.         inorder(bt->lchild, visit);  
  5.         visit(bt->data);  
  6.         inorder(bt->rchild, visit);  
  7.     }  
  8. }  
[cpp] view plaincopy
  1. void postorder(bitree bt, int (*visit)(elemtype e))  
  2. {  
  3.     if (bt) {  
  4.         postorder(bt->lchild, visit);  
  5.         postorder(bt->rchild, visit);  
  6.         visit(bt->data);  
  7.     }  
  8. }  
二叉树的递归算法较简单,代码简洁清晰,但递归算法效率低,执行速度慢,在下一节将说到二叉树非递归遍历算法。
  • 求二叉树的深度
[cpp] view plaincopy
  1. int get_tree_depth(bitree bt)  
  2. {  
  3.     int ldepth, rdepth;  
  4.   
  5.     if (!bt)  
  6.         return 0;  
  7.     else if (!bt->lchild && !bt->rchild)  
  8.         return 1;  
  9.     else {  
  10.         ldepth = get_tree_depth(bt->lchild);  
  11.         rdepth = get_tree_depth(bt->rchild);  
  12.   
  13.         return (ldepth > rdepth ? ldepth : rdepth) + 1;  
  14.     }  
  15. }  
树的深度即树的结点中最大层次,分别递归求左右子树的深度,较大子树深度为树的深度。
  • 求叶子结点数
[cpp] view plaincopy
  1. int get_num_of_leave(bitree bt)  
  2. {  
  3.     if (!bt)  
  4.         return 0;  
  5.     else if (!bt->lchild && !bt->rchild)  
  6.         return 1;  
  7.     else  
  8.         return (get_num_of_leave(bt->lchild) + get_num_of_leave(bt->rchild));  
  9. }  
递归求左右子树的叶子数,左右子树的叶子结点之和为树的叶子结点数。
  • 释放二叉树
[cpp] view plaincopy
  1. void free_bitree(bitree *bt)  
  2. {  
  3.     if (*bt) {  
  4.         if ((*bt)->lchild)  
  5.             free_bitree(&(*bt)->lchild);  
  6.         if ((*bt)->rchild)  
  7.             free_bitree(&(*bt)->rchild);  
  8.             free(*bt);  
  9.             *bt = NULL;  
  10.     }  

原创粉丝点击