int isBSTError(BTNode *root) { if (!root) return 1; if (root->left && root->left->value >= root->value) return 0; if (root->right && root->right->value < root->value) return 0; if (!isBSTError(root->left) || !isBSTError(root->right)) return 0; return 1; }
10 / \ 5 15 -------- binary tree(1) 符合上述条件的二叉树,但是并不是二叉搜索树。 / \ 6 20
int isBSTUnefficient(BTNode *root) { if (!root) return 1; if (root->left && bstMax(root->left)->value >= root->value) return 0; if (root->right && bstMin(root->right)->value < root->value) return 0; if (!isBSTUnefficient(root->left) || !isBSTUnefficient(root->right)) return 0; return 1; }
int isBSTEfficient(BTNode* root, BTNode *left, BTNode *right) { if (!root) return 1; if (left && root->value <= left->value) return 0; if (right && root->value > right->value) return 0; return isBSTEfficient(root->left, left, root) && isBSTEfficient(root->right, root, right); }
int isBSTInOrder(BTNode *root, BTNode *prev) { if (!root) return 1; if (!isBSTInOrder(root->left, prev)) return 0; if (prev && root->value < prev->value) return 0; return isBSTInOrder(root->right, root); }
int isCompleteBTLevelOrder(BTNode *root) { if (!root) return 1; BTNodeQueue *queue = queueNew(btSize(root)); enqueue(queue, root); int flag = 0; while (QUEUE_SIZE(queue) > 0) { BTNode *node = dequeue(queue); if (node->left) { if (flag) return 0; enqueue(queue, node->left); } else { flag = 1; } if (node->right) { if (flag) return 0; enqueue(queue, node->right); } else { flag = 1; } } return 1; }
10(0) / \ 5(1) 15(2) - 结点数目为5,如果是完全二叉树结点最大的序号应该是4,而它的是6,所以不是。 / \ 6(5) 20(6)
int isCompleteBTIndexMethod(BTNode *root, int index, int nodeCount) { if (!root) return 1; if (index >= nodeCount) return 0; return (isCompleteBTIndexMethod(root->left, 2*index 1, nodeCount) && isCompleteBTIndexMethod(root->right, 2*index 2, nodeCount)); }
__2__ / \ 1 4 ---- 平衡二叉树示例 \ / \ 3 5 6
int isBalanceBTTop2Down(BTNode *root) { if (!root) return 1; int leftHeight = btHeight(root->left); int rightHeight = btHeight(root->right); int hDiff = abs(leftHeight - rightHeight); if (hDiff > 1) return 0; return isBalanceBTTop2Down(root->left) && isBalanceBTTop2Down(root->right); }
int isBalanceBTDown2Top(BTNode *root, int *height) { if (!root) { *height = 0; return 1; } int leftHeight, rightHeight; if (isBalanceBTDown2Top(root->left, &leftHeight) && isBalanceBTDown2Top(root->right, &rightHeight)) { int diff = abs(leftHeight - rightHeight); return diff > 1 ? 0 : 1; } return 0; }
5 9 6 / \ / \ / \ 1 2 7 12 5 9 / \ / \ \ 4 3 5 8 10 二叉树(1) 二叉树(2) 二叉树(3)
int isOmorphism(BTNode *t1, BTNode *t2) { if (!t1 || !t2) return (!t1) && (!t2); return isOmorphism(t1->left, t2->left) && isOmorphism(t1->right, t2->right); }
1 1 / / 2 2 \ / 3 3 先序遍历:1 2 3 后序遍历:3 2 1
先序遍历:7 10 4 3 1 2 8 11 中序遍历:4 10 3 1 7 11 8 2 二叉树如下: 7 / \ 10 2 / \ / 4 3 8 \ / 1 11
/** * 辅助函数,查找根结点在中序遍历中的位置。 */ int findBTRootIndex(int inorder[], int count, int rootVal) { int i; for (i = 0; i < count; i ) { if (inorder[i] == rootVal) return i; } return -1; } /** /** * 根据先序和中序遍历构建二叉树 */ BTNode *buildBTFromPreInOrder(int preorder[], int inorder[], int n, int offset, int count) { if (n == 0) return NULL; int rootVal = preorder[0]; int rootIndex = findBTRootIndex(inorder, count, rootVal); int leftCount = rootIndex - offset; // 左子树结点数目 int rightCount = n - leftCount - 1; // 右子树结点数目 BTNode *root = btNewNode(rootVal); root->left = buildBTFromPreInOrder(preorder 1, inorder, leftCount, offset, count); root->right = buildBTFromPreInOrder(preorder leftCount 1, inorder, rightCount, offset leftCount 1, count); return root; }
中序遍历:4 10 3 1 7 11 8 2 后序遍历:4 1 3 10 11 8 2 7 二叉树如下: 7 / \ 10 2 / \ / 4 3 8 \ / 1 11
/** * 根据中序和后序遍历构建二叉树 */ BTNode *buildBTFromInPostOrder(int postorder[], int inorder[], int n, int offset, int count) { if (n == 0) return NULL; int rootVal = postorder[n-1]; int rootIndex = findBTRootIndex(inorder, count, rootVal); int leftCount = rootIndex - offset; // 左子树结点数目 int rightCount = n - leftCount - 1; // 右子树结点数目 BTNode *root = btNewNode(rootVal); root->left = buildBTFromInPostOrder(postorder, inorder, leftCount, offset, count); root->right = buildBTFromInPostOrder(postorder leftCount, inorder, rightCount, offset leftCount 1, count); return root; }
30 / \ 20 40 / / \ 10 35 50
50 / 40 / 35 / 30 / 20 / 10
/** * 存储二叉树到文件中-使用先序遍历 */ void bstSave(BTNode *root, FILE *fp) { if (!root) return; char temp[30]; sprintf(temp, "%d\n", root->value); fputs(temp, fp); bstSave(root->left, fp); bstSave(root->right, fp); } /** * 从文件中恢复二叉树 */ BTNode *bstRestore(FILE *fp) { BTNode *root = NULL; char *s; char buf[30]; while ((s = fgets(buf, 30, fp))) { int nodeValue = atoi(s); root = bstInsert(root, nodeValue); } return root; }
30 / \ 10 20 / / \ 50 45 35
/** * 存储二叉树到文件中 */ void btSave(BTNode *root, FILE *fp) { if (!root) { fputs("#\n", fp); } else { char temp[30]; sprintf(temp, "%d\n", root->value); fputs(temp, fp); btSave(root->left, fp); btSave(root->right, fp); } } /** * 从文件恢复二叉树 */ BTNode *btRestore(BTNode *root, FILE *fp) { char buf[30]; char *s = fgets(buf, 30, fp); if (!s || strcmp(s, "#\n") == 0) return NULL; int nodeValue = atoi(s); root = btNewNode(nodeValue); root->left = btRestore(root->left, fp); root->right = btRestore(root->right, fp); return root; }
______6______ / \ __2__ __8__ / \ / \ 0 4 7 9 / \ 3 5
BTNode *bstLCA(BTNode *root, BTNode *p, BTNode *q) { if (!root || !p || !q) return NULL; int maxValue = p->value >= q->value ? p->value : q->value; int minValue = p->value < q->value ? p->value : q->value; if (maxValue < root->value) { return bstLCA(root->left, p, q); } else if (minValue > root->value) { return bstLCA(root->right, p, q); } else { return root; } }
_______3______ / \ ___5__ ___1__ / \ / \ 6 2 0 8 / \ 7 4
/** * 二叉树最低公共祖先结点-自顶向下解法 O(N^2) */ BTNode *btLCATop2Down(BTNode *root, BTNode *p, BTNode *q) { if (!root || !p || !q) return NULL; if (btExist(root->left, p) && btExist(root->left, q)) { return btLCATop2Down(root->left, p, q); } else if (btExist(root->right, p) && btExist(root->right, q)) { return btLCATop2Down(root->right, p, q); } else { return root; } } /** * 二叉树结点存在性判断 */ int btExist(BTNode *root, BTNode *node) { if (!root) return 0; if (root == node) return 1; return btExist(root->left, node) || btExist(root->right, node); }
/** * 二叉树最低公共祖先结点-自底向上解法 O(N) */ BTNode *btLCADown2Top(BTNode *root, BTNode *p, BTNode *q) { if (!root) return NULL; if (root == p || root == q) return root; BTNode *left = btLCADown2Top(root->left, p, q); BTNode *right = btLCADown2Top(root->right, p, q); if (left && right) return root; // 如果p和q位于不同的子树 return left ? left: right; //p和q在相同的子树,或者p和q不在子树中 }
___10___ / \ _5_ 15 / \ \ 1 8 7 ___10____ / \ _5_ 15 -------- subtree (1) / \ 1 8 _5_ / \ -------- subtree (2) 1 8
/** * 查找二叉树最大的二叉搜索子树-自顶向下方法 */ BTNode *largestSubBSTTop2Down(BTNode *root, int *bstSize) { if (!root) { *bstSize = 0; return NULL; } if (isBSTEfficient(root, NULL, NULL)) { //以root为根结点的树为BST,则设置结果为root并返回。 *bstSize = btSize(root); return root; } int lmax, rmax; BTNode *leftBST = largestSubBSTTop2Down(root->left, &lmax); //找出左子树中为BST的最大的子树 BTNode *rightBST = largestSubBSTTop2Down(root->right, &rmax); //找出右子树中为BST的最大的子树 *bstSize = lmax > rmax ? lmax : rmax; //设定结点最大数目 BTNode *result = lmax > rmax ? leftBST : rightBST; return result; }
/** * 查找二叉树最大的二叉搜索子树-自底向上方法 */ BTNode *largestSubBSTDown2Top(BTNode *root, int *bstSize) { BTNode *largestBST = NULL; int min, max, maxNodes=0; findLargestSubBST(root, &min, &max, &maxNodes, &largestBST); *bstSize = maxNodes; return largestBST; } /** * 查找最大二叉搜索子树自底向上方法主体函数 * 如果是BST,则返回BST的结点数目,否则返回-1 */ int findLargestSubBST(BTNode *root, int *min, int *max, int *maxNodes, BTNode **largestSubBST) { if (!root) return 0; int isBST = 1; int leftNodes = findLargestSubBST(root->left, min, max, maxNodes, largestSubBST); int currMin = (leftNodes == 0) ? root->value : *min; if (leftNodes == -1 || (leftNodes != 0 && root->value <= *max)) isBST = 0; int rightNodes = findLargestSubBST(root->right, min, max, maxNodes, largestSubBST); int currMax = (rightNodes == 0) ? root->value : *max; if (rightNodes == -1 || (rightNodes != 0 && root->value > *min)) isBST = 0; if (!isBST) return -1; *min = currMin; *max = currMax; int totalNodes = leftNodes rightNodes 1; if (totalNodes > *maxNodes) { *maxNodes = totalNodes; *largestSubBST = root; } return totalNodes; }
___1___ / \ 2 3 / \ / \ 4 5 6 7 \ 8 Distance(4, 5) = 2 Distance(4, 6) = 4 Distance(3, 4) = 3 Distance(2, 4) = 1 Distance(8, 5) = 5
/** * 计算二叉树两个结点最短距离 */ int distanceOf2BTNodes(BTNode *root, BTNode *p, BTNode *q) { if (!root) return 0; BTNode *lca = btLCADown2Top(root, p, q); int d1 = btDistanceFromRoot(lca, p, 0); int d2 = btDistanceFromRoot(lca, q, 0); return d1 d2; } /** * 计算二叉树结点node和root的距离 */ int btDistanceFromRoot(BTNode *root, BTNode *node, int level) { if (!root) return -1; if (root == node) return level; int left = btDistanceFromRoot(root->left, node, level 1); if (left == -1) return btDistanceFromRoot(root->right, node, level 1); return left; }
/** * 计算BST两个结点最短距离。 */ int distanceOf2BSTNodes(BTNode *root, BTNode *p, BTNode *q) { if (!root) return 0; if (root->value > p->value && root->value > q->value) { return distanceOf2BSTNodes(root->left, p, q); } else if(root->value <= p->value && root->value <= q->value){ return distanceOf2BSTNodes(root->right, p, q); } else { return bstDistanceFromRoot(root, p) bstDistanceFromRoot(root, q); } } /** * 计算BST结点node和root的距离 */ int bstDistanceFromRoot(BTNode *root, BTNode *node) { if (root->value == node->value) return 0; else if (root->value > node->value) return 1 bstDistanceFromRoot(root->left, node); else return 1 bstDistanceFromRoot(root->right, node); }
___10___ / \ _5_ 15 ------ 第1种情况 / \ \ 1 8 7 10 / 5 / \ ------ 第2种情况 1 8 / \ 2 3
int btMaxDistance(BTNode *root, int *maxDepth) { if (!root) { *maxDepth = 0; return 0; } int leftMaxDepth, rightMaxDepth; int leftMaxDistance = btMaxDistance(root->left, &leftMaxDepth); int rightMaxDistance = btMaxDistance(root->right, &rightMaxDepth); *maxDepth = max(leftMaxDepth 1, rightMaxDepth 1); int maxDistance = max3(leftMaxDistance, rightMaxDistance, leftMaxDepth rightMaxDepth); // max求两个数最大值,max3求三个数最大值,详见代码 return maxDistance; }
1 / \ 2 3 / \ \ 4 5 8 / \ 6 7
/** * 二叉树最大宽度 */ int btMaxWidth(BTNode *root) { int h = btHeight(root); int level, width; int maxWidth = 0; for (level = 1; level <= h; level ) { width = btLevelWidth(root, level); if (width > maxWidth) maxWidth = width; } return maxWidth; } /** * 二叉树第level层的宽度 */ int btLevelWidth(BTNode *root, int level) { if (!root) return 0; if (level == 1) return 1; return btLevelWidth(root->left, level-1) btLevelWidth(root->right, level-1); }
/** * 二叉树最大宽度-先序遍历法 */ int btMaxWidthPreOrder(BTNode *root) { int h = btHeight(root); int *count = (int *)calloc(sizeof(int), h); btLevelWidthCount(root, 0, count); int i, maxWidth = 0; for (i = 0; i < h; i ) { if (count[i] > maxWidth) maxWidth = count[i]; } return maxWidth; } /** * 计算二叉树从 level 开始的每层宽度,并存储到数组 count 中。 */ void btLevelWidthCount(BTNode *root, int level, int count[]) { if (!root) return; count[level] ; btLevelWidthCount(root->left, level 1, count); btLevelWidthCount(root->right, level 1, count); }
__3__ / \ 1 5 ---- 平衡二叉搜索树示例 \ / \ 2 4 6
BTNode *sortedArray2BST(int a[], int start, int end) { if (start > end) return NULL; int mid = start (end-start)/2; BTNode *root = btNewNode(a[mid]); root->left = sortedArray2BST(a, start, mid-1); root->right = sortedArray2BST(a, mid 1, end); return root; }
BTNode *sortedList2BST(ListNode **pList, int start, int end) { if (start > end) return NULL; int mid = start (end-start)/2; BTNode *left = sortedList2BST(pList, start, mid-1); BTNode *parent = btNewNode((*pList)->value); parent->left = left; *pList = (*pList)->next; parent->right = sortedList2BST(pList, mid 1, end); return parent; }
void bt2DoublyList(BTNode *node, BTNode **pPrev, BTNode **pHead) { if (!node) return; bt2DoublyList(node->left, pPrev, pHead); // 当前结点的left指向前一个结点pPrev node->left = *pPrev; if (*pPrev) (*pPrev)->right = node; // 前一个结点的right指向当前结点 else *pHead = node; // 如果前面没有结点,则设置head为当前结点(当前结点为最小的结点)。 // 递归结束后,head的left指针指向最后一个结点,最后一个结点的右指针指向head结点。 // 注意保存当前结点的right指针,因为在后面代码中会修改该指针。 BTNode *right = node->right; (*pHead)->left = node; node->right = (*pHead); *pPrev = node;//更新前一个结点 bt2DoublyList(right, pPrev, pHead); }