这次讲讲树。
首先上定义:
如上图所示,这就是子树相交的情况。
树的层(level)的概念是从根开始定义的,根是第一层,根的孩子为第二层,如此类推。
此外,如果将树中结点的子树看成从左至右有次序,不能互换,那么称为有序树,否则称为无序树。
其实上面的大概知道就可以了,因为真正的重点是二叉树。
所有结点只有左子树就是左斜树, 反之是右斜树,两者统称斜树。
即一颗二叉树中,所有分支结点都存在左子树和右子树,并且所有叶子都在同一层上。
完全二叉树和满二叉树的不同在于,完全二叉树是满二叉树的子集,满二叉树一定是完全二叉树,完全二叉树不一定是满二叉树。
此外,完全二叉树的结点与同样深度的满二叉树,在按照层序编号的时候编号是一一对应的。例如:
所以判断一个二叉树是不是完全二叉树的方法就是:直接给每个结点按照层序进行编号,如果编号出现空当那么就说明不是完全二叉树。
性质1的证明(这里的性质都是用数学归纳法证明的):
叶子结点:5(图中白色部分),度为2节点:4(图中深色部分)。
性质4:
可以直接通过性质2证明,这里就不多说了。
性质5:
分顺序存储结构和链式存储结构,顺序存储结构只能在二叉树是完全二叉树的情况下使用,不怎么用这种存储方式,所以这里就不说了。重点是二叉链表。
就是这玩意,data
是数据域,lchild
和rchild
是指针域,分别指向左孩子和右孩子。
定义代码:
typedef struct BiTNode {
TElemType data;
struct BiTNode *lchild, *rchild;
} BiTNode, *BiTree;
在这个结构的基础上建立的二叉树的结构如下图所示:
在这个基础上还有一些改进的版本,如为了更快速地进行遍历,添加了指向兄弟节点的指针域,这里就不提了。
口诀:根左右。以此来分析下上图,首先从根开始,所以A,然后左,所以B,此时根设定为B,继续,左,D,左,G。G为根的时候发现没有左孩子和右孩子,所以返回D,最后,右,H。H没有孩子,所以返回D,D已经遍历过了,以此类推,返回到A,开始右,C。然后还是左,E,根结点为E时发现没有左孩子,所以遍历到I,最后I没有孩子,所以返回到E,E已经遍历过了,所以回到C,开始遍历右侧,所以F。所以最后的输出顺序是ABDGHCEIF。
口诀:左根右(当成优先级来看待,优先遍历最左边的,其次根,最后右)
前中后序遍历的C++实现:
/* Given a binary tree, print its nodes according to the
"bottom-up" postorder traversal. */
// 后序
void printPostorder(struct Node* node)
{
if (node == NULL)
return;
// first recur on left subtree
printPostorder(node->left);
// then recur on right subtree
printPostorder(node->right);
// now deal with the node
// 注意这行的位置,其实前中后序的实现组合是一样的,只是顺序不一样
cout << node->data << " ";
}
/* Given a binary tree, print its nodes in inorder*/
// 中序
void printInorder(struct Node* node)
{
if (node == NULL)
return;
/* first recur on left child */
printInorder(node->left);
/* then print the data of node */
cout << node->data << " ";
/* now recur on right child */
printInorder(node->right);
}
/* Given a binary tree, print its nodes in preorder*/
// 前序
void printPreorder(struct Node* node)
{
if (node == NULL)
return;
/* first print data of node */
cout << node->data << " ";
/* then recur on left sutree */
printPreorder(node->left);
/* now recur on right subtree */
printPreorder(node->right);
}
《大话数据结构》:其实这本入门看看还行,深入的话还得看别的书……
Tree Traversals (Inorder, Preorder and Postorder)
关于前中后序排列