简介
前面介绍过二叉树的数据结构,它的逻辑很简单,除了根结点之外每个结点只有一个父节点,除了叶结点之外所有的结点都有一个或多个子节点。父和子之间用指针连接。
二叉树有三种变量方式:
-前序遍历:根左右
-中序遍历:左根右
-后序遍历:左右根
题目1:重建二叉树
输入某二叉树的前 序遍历和中序遍历的结果,重建该二叉树
struct BinaryTreeNode//结点结构 { int _value; BinaryTreeNode* _left; BinaryTreeNode* _right; BinaryTreeNode(const int&x) { _value = x; _left = NULL; _right = NULL; } }; BinaryTreeNode* Construct(int * prevOrder, int *inOrder, int length) { if (prevOrder == NULL || inOrder == NULL || length == 0) return; return ConstructCore(prevOrder,prevOrder+length-1,inOrder,inOrder+length-1) } BinaryTreeNode*ConstructCore(int* PrevHead, int*prevTail, int*inHead, int*inTail) { //前序遍历的第一个节点即为根结点 BinaryTreeNode* root = new BinaryTreeNode(PrevHead[0]); //只有一个节点 if (PrevHead == prevTail) { if (inHead == inTail) return root; else throw std::exception("Invalid inPut");//抛出异常 } //在中序结点中找到根结点的值 int *InorderRoot = inHead; while (InorderRoot<=inTail&&InorderRoot != PrevHead) { InorderRoot++; } if (InorderRoot == inTail&&*InorderRoot != PrevHead[0]) throw std::exception("Invalid input"); int leftLength = InorderRoot - inHead; int* leftPrevOrderTail = PrevHead + leftLength; if (leftLength > 0) { //构建左子树 root->_left = ConstructCore(PrevHead + 1, leftPrevOrderTail, inHead, InorderRoot - 1); } if (leftLength < prevTail - PrevHead) { //构建右子树 root->_right = ConstructCore(leftPrevOrderTail + 1, prevTail, InorderRoot + 1, inTail); } return root; }
题目二:二叉树的镜像
先前序遍历这棵树的结点,若遍历到的结点有子节点,就交换这个两个子节点,当交换完成所有非叶子结点的左右结点之后,就得到数的镜像
void MirrorRecursively(BinaryTreeNode *pRoot) { if ((pRoot == NULL)||(pRoot->m_pLeft==NULL&&pRoot->m_pRight==NULL)) return; swap(pRoot->m_pLeft, pRoot->m_pRight); if (pRoot->m_pLeft) MirrorRecursively(pRoot->m_pLeft); if (pRoot->m_pRight) MirrorRecursively(pRoot->m_pRight); }
题目三:输入两颗二叉树A和B,判断B不是A的子结构
bool HasSubTree(BinaryTreeNode*pRoot1, BinaryTreeNode*pRoot2) { BinaryTreeNode* pcur1 = pRoot1; BinaryTreeNode* pcur2 = pRoot2; bool result = false; if (pRoot1 != NULL || pRoot2 != NULL) { if (pcur1->m_value == pcur2->m_value) result = DoseTree1HaveTree2(pcur1, pcur2); if (!result) result = HasSubTree(pcur1->m_pLeft, pcur2); if (!result) result = HasSubTree(pcur1->m_pRight, pcur2); } return result; } bool DoseTree1HaveTree2(BinaryTreeNode* pRoot1, BinaryTreeNode* pRoot2) { if (pRoot2 == NULL) return true; if (pRoot2 == NULL) return false; if (pRoot1->m_value != pRoot2->m_value) return false; return DoseTree1HaveTree2(pRoot1->m_pLeft, pRoot1->m_pLeft) && DoseTree1HaveTree2(pRoot1->m_pRight, pRoot2->m_pRight); }
题目四:层序遍历二叉树
void PrintLevelOrder(BinaryTreeNode<T>*root) { if (root == NULL) return; queue<BinaryTreeNode<T>*>q1; q1.push(root); while (q1.size() != 0) { if (q1.front()->_left) { q1.push(q1.front()->_left); } if (q1.front()->_right) { q1.push(q1.front()->_right); } cout << q1.front()->_value << " "; q1.pop(); } }
题目五:前序非递归实现
void PrintPrevOrder(BinaryTreeNode<T>root) { if(root==NULL) return; stack<BinaryTreeNode<T>*>s; s.push(root); while(s.size()>0) { BinaryTreeNode<T>*cur=s.top(); s.pop(); cout<<cur->_value<<" "; if(root->_right!=NULL) s.push(root->_right); if(root->_left!=NULL) s.push(root->_left); } }
题目六:中序的非递归实现
void PrintInOrder(BinaryTreeNode<T>root) { stack<BinaryTreeNode<T>*>s; BinaryTreeNode<T>*cur=root; while(cur||s.size>0) { s.push(cur); while(cur->_left) { s.pusu(cur->_left); cur=cur->_left; } cout<<s.top()->_value<<" "; cur=s.top()->_right; s.pop(); } }
题目七:后序的非递归实现
void PrintPostOrder(BinaryTreeNode<T>*root) { stack<BinaryTreeNode<T>*>s; BinaryTreeNode<T>*cur = root; BinaryTreeNode<T>*prev = NULL; while (cur || s.size() > 0) { while (cur != NULL) { s.push(cur); cur = cur->_left; } cur = s.top(); if (cur->_right == NULL || cur->_right == prev) { cout << cur->_value << " "; prev = cur; cur = NULL; s.pop(); } else { cur = cur->_right; } } }
题目八:二叉搜索树的后序遍历
输入一个整数数组,判断该数组是不是某二叉树的后序遍历结果,如果是返回true,否则返回false
bool VerifySquenceOfBST(int sequence[], int length) { if (sequence == NULL || length <= 0) return false; int root = sequence[length - 1]; size_t i = 0; for ( i = 0; i < length - 1; i++) { if (sequence[i]>root) break; } size_t j = i; for (; j < length; j++) { if (sequence[j] < root) return false; } bool left = true; left = VerifySquenceOfBST(sequence, i); bool right = true; right = VerifySquenceOfBST(sequence + i, length - i - i); return left&&right; }
题目九:二叉树中和为某一值的路径
输入一个二叉树和一个整数,打印出二叉树中结点值的和为输入整数的所有路径,从树的根开始往下一直到叶形成一条路径
void Findpath(BinatryTreeNode<T>*root, T sum) { if (root == NULL) return; vector<BinatryTreeNode<T>*> path; int curSum = 0; _FindPath(root, sum, path, curSum); } private: void _FindPath(BinatryTreeNode<T>*root, const T&sum, vector<BinaryTreeNode<T>*>&path, T&curSum) { curSum_ += root->_value; path.push_back(root); //如果为叶结点且路径值相等则输出路径 bool IsLeaf = root->_right == NULL&&root->_left == NULL; if (curSum == sum&&IsLeaf) { for (size_t i = 0; i < path.size(); i++) { cout << path[i]->_value << " "; } } //若不是叶结点遍历至叶结点 if (root->_left != NULL) _FindPath(root->_left, sum, path, curSum); if (root->_right != NULL) _FindPath(root->_right, sum, path, curSum); curSum -= root->_value; path.pop_back(); }