树属于非线性数据结构,它是一种层次结构:如果存在前驱节点,则是唯一
的,如果存在后继节点,则可以是多个。即树的元素之间是一对多的关系。
树是由n个节点构成的有限集合T,如果n = 0,则是空树,如果n不等于0,则
一个非空树,有且只有一个根结点root,如果n>1,则除了根结点外,其余节
点又可以划分为有限集T1,T2......Tm 其中每个有限集有是一棵树。称为子
树subtree.
树的存储结构
双亲表示法
孩子表示法
孩子兄弟表示法(二叉树表示法)
森林:M棵互不相交的树的集合。
二叉树:
二叉树的特点是每个节点至多只有两颗子树,并且二叉树的子树有左右之
分,它的次序不能任意颠倒。
二叉树的特点:
在二叉树的第i层上至多有2的i-1次方个节点
深度为k的二叉树至多有2的k次方-1个节点
如果一颗二叉树的终端节点的数目为i,深度为2的节点数目为j,则i=j+1
满二叉树:深度为k且节点数目为2的k次方-1的二叉树
完全二叉树:只有在最下面一层的右边缺少若干个节点的满二叉树
二叉树的存储结构:
按顺序储存,即使用一组连续的储存单元,自上而下,自左而右的储存,每
个空节点也会占用一个储存单元。这样的储存方式只适合完全二叉树,因为
会浪费大量空间。
链式储存结构:二叉树的节点至少包括三个域,数据域和指向左右子树的指
针域,有时候也增加一个指向双亲的指针域来方便指向节点的双亲。
二叉树的遍历:以一定的规则将非线性的节点排列成线性序列
先序遍历二叉树:
先访问根结点,再先序遍历左子树,最后先序遍历右子树
中序遍历二叉树
先中序遍历左子树,在访问根结点,最后中序遍历右子树
后序遍历二叉树
先后序遍历左子树,在后序遍历右子树,最后访问根结点
在已知两种遍历的情况下可以得出原二叉树的形状,这两种遍历可以是先序
和后序,也可以是中序和后序
// 二叉树的初始化 void Init_BitTree(BiTree * T) { *T = NULL; return; } // 销毁二叉树 void Destroy_BitTree(BiTree * T) { if ((*T)->lchild) Destroy_BitTree(&((*T)->lchild)); if ((*T)->rchild) Destroy_BitTree(&((*T)->rchild)); free(*T); *T = NULL; return; } // 二叉树的插入,通过判断LR的值,判断插入选择 int Insert_Child(BiTree p, int LR, BiTree c) { if (p) // p指向的二叉树非空 { if (0 == LR) { c->rchild = p->lchild; // p原来的左子树称为c的右子树 p->lchild = c; // 子树c作为p的左子树 } else { c->rchild = p->rchild; p->rchild = c; return 1; } } return 0; } // 返回二叉树e的左孩子节点的元素值 int Left_Child(BiTree T, int e) { BiTree p; if (T) // 当二叉树T不为空时 { p = Point(T, e); // p是元素值e的节点的指针 if (p && p->lchild) // 如果p的节点不为空,且p的左孩子节点存在 return p->lchild->data; // 返回左孩子节点的元素值 } return 0; } // 返回二叉树e的右孩子节点的元素值 int Right_Child(BiTree T, int e) { BiTree p; if (T) // 当二叉树T不为空时 { p = Point(T, e); // p是元素值e的节点的指针 if (p && p->rchild) // 如果p的节点不为空,且p的左右孩子节点存在 return p->rchild->data; // 返回右孩子节点的元素值 } return 0; } // 在二叉树中寻找元素值为e的节点,此处假定该二叉树的节点元素值各不相同,如果找到返回该节点的地址,否则返回NULL BiTree Point(BiTree T, int e) { if (e == T->data) { return T; } else { if (T->lchild != NULL) Point(T->lchild, e); if (T->rchild != NULL) Point(T->rchild, e); } return NULL; } // 删除子树操作,根据LR的值选择删除的是左子树还是右子树 int Delete_Child(BiTree p, int LR) { if (p) // 判断p不空 { if (0 == LR) Destroy_BitTree(&(p->lchild)); else Destroy_BitTree(&(p->rchild)); return 1; } return 0; }