锲而不舍,金石可镂
一. 一些基本概念
(1)树:树结构是以分支关系定义的一种层次数据结构,应用树结构组织起来的数据具有层次关系。除根节点之外每个节点只有一个父节点,根节点没有父节点;除叶节点之外每个节点都有一个或多个子节点,叶节点无子节点。父节点和子节点之间通过指针进行链接。
-
常见名词:
-
- 节点的度: 节点拥有子树的数目
-
- 树的度: 树中各节点度的最大值
-
- 树的深度: 树中各节点的最大深度
-
性质:
-
- 非空树的节点总数等于树中所有节点的度之和加1。
-
- 度为k的非空树的第i层最多有k的i-1次方个节点
-
- 深度为h的k叉树最多有(k^h-1)/(k-1)个节点
(2)二叉树:二叉树是一种特殊的树结构,每个节点最多只有两个孩子节点。左子树和右子树次序不能够颠倒,是一种有序树。
//二叉树节点定义
typedef struct BINARYNODE{
int value;
struct BINARYNODE* lchild;
struct BINARYNODE* rchild;
}BinaryNode;
(3)满二叉树:一棵深度为k且有2^k-1个节点的二叉树
(4)完全二叉树:除最后一层外,每层上节点数均达最大值,在最后一层上只缺少右边的若干节点的二叉树
(5)二叉树的遍历:
- 先序遍历: 先访问根节点,再访问左节点,最后访问右节点。
- 中序遍历: 先访问左节点,再访问根节点,最后访问右节点。
- 后序遍历: 先访问左节点,再访问右节点,最后访问根节点。
二. 代码实现
1. 使用递归方法由某二叉树的前序遍历和中序遍历的结果重建该二叉树
BinaryNode* Construct (int* preorder, int* inorder, int length){
if (preorder == NULL || inorder == NULL || length <= 0){
return;
}
return ConstructCore (preorder, preorder + length - 1, inorder, inoorder + length - 1);
}
BinaryNode* ConstructCore(int* preBegin, int* preEnd,int* inBegin, int* inEnd){
if (inEnd == inBegin) return NULL;
BinaryNode* cur = new BinaryNode(*preBegin);
auto root = find(inBegin, inEnd, *preBegin);
cur -> left = ConstructCore(preBegin + 1, preBegin + (root - inBegin) + 1, inBegin, root);
cur -> right = ConstructCore(preBegin + 1 + (root - inBegin), preEnd, root + 1, inEnd);
return cur;
}
2. 给定一棵二叉树和其中一个节点,找出中序遍历的下一节点
BinaryNode* GetNext (BinaryNode* pNode){
if (pNode == NULL) return;
BinaryNode* pNext == NULL;
if (pNode -> right != NULL){
BinaryNode* pRight = pNode -> right;
while(pRight -> left != NULL){
pRight = pRight -> left;
}
pNext = pRight;
}
else if (pNode -> parent != NULL){
BinaryNode* pCurrent = pNode;
BinaryNode* pParent = pNode -> parent;
while (pParent != NULL && pCurrent == pParent -> right){
pCurrent = pParent;
pParent = pParent -> parent;
}
pNext = pParent;
}
return pNext;
}