简介

    前面介绍过二叉树的数据结构,它的逻辑很简单,除了根结点之外每个结点只有一个父节点,除了叶结点之外所有的结点都有一个或多个子节点。父和子之间用指针连接。

    二叉树有三种变量方式:

    -前序遍历:根左右

    -中序遍历:左根右

    -后序遍历:左右根

题目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();
	}