C ++实现二叉树及笔试题(2)

1.求二叉树中最远的两个节点的距离;即求宽度

2.由前序遍历和中序遍历重建二叉树

3.将二叉搜索树转换成一个排序的双向链表。要求不能创建任何新的结点,只能调整树中结点指针的指向;

4.判断一颗二叉树是否是另一颗树的子树。

BinaryTree.h 实现

//#pragma once
#ifndef  _BINARYTREE_H
#define _BINARYTREE_H

#include<iostream>
#include<queue>
#include<stack>
#include<deque>
using namespace std;
template <class T>
class BinTreeNode
{
public:
	BinTreeNode() :left(NULL), right(NULL) {}
	BinTreeNode(T v) :left(NULL), right(NULL), data(v) {}
	~BinTreeNode(){}


public:
	T data;
	BinTreeNode<T> *left, *right;
};

template <class T>
class BinaryTree
{
public:
	BinaryTree() :root(NULL), flag('#') {}
	BinaryTree(T v) :root(NULL),flag(v) {}
public:
	void CreateBinTree(const T *&str)
	{
		CreateBinTree(root, str);
	}
	//已知前序和中序遍历创建树
	void CreateBinTree_VLR_LVR(const char *vlr, const char *lvr)
	{
		int n = strlen(vlr);
		root = CreateBinTree_VLR_LVR(vlr, lvr, n);
	}
	//同理有已知后续和中序创建树
	void CreateBinTree_LVR_LRV(const char *lvr,const int *lrv){}
	//树的叶子结点数
	int LeafSize()const { return LeafSize(root); }
	//树的结点数
	int size() { return size(root); }
	//树的高度
	int height() { return height(root); }
	//树的高度
	int Weight() { return Weight(root); }
	/*********************采用递归*********************************************/
	void PreOrder() const{PreOrder(root);}//前序遍历
	void InOrder()const {InOrder(root);}//中序遍历
	void PostOrder()const {PostOrder(root);}//后序遍历
	void LeveLOrder() const { LeveLOrder(root); }//层遍历
	/*********************采用非递归*******************************************/
	void Non_Recursive_PreOrder()const { Non_Recursive_PreOrder(root); }
	void Non_Recursive_InOrder() const { Non_Recursive_InOrder(root); }
	void Non_Recursive_PostOrder()const { Non_Recursive_PostOrder(root); }
	/*************************************************************************/
	//判断一个颗树是否是树的子树
	bool Equal_Is_Subtree(BinaryTree<T> &bt)
	{
		BinTreeNode<T> *tmp= Find(bt.root->data);
		return Equal(tmp, bt.root);
	}
	//判断两个二叉树是否相等
	bool Equal(BinaryTree<T> &bt)
	{
		return Equal(root, bt.root);
	}
	//将二叉树转换成双向循环链表
	BinTreeNode<T>* ConvertList()
	{
		return ConvertList(root);
	}
	//判断值是否存在在节点中
	bool IsInTree(const T&key)
	{
		return IsInTree(root, key);
	}
	//交换左右子数
	void SwapLeftRightChild() { SwapLeftRightChild(root); }
	//求两个结点的最近的父节点
	BinTreeNode<T>* CommonParent(const T &x, const T &y)
	{
		BinTreeNode<T> *px = Find(root, x);
		BinTreeNode<T> *py = Find(root, y);
		if (px == NULL || py == NULL)
		{
			return NULL;
		}
		return CommonParent(root, px, py);
	}
	//查找结点
	BinTreeNode<T>* Find(const T &key)
	{
		return Find(root, key);
	}
	//求一个结点的父结点
	BinTreeNode<T>*Parent(const T &key)
	{
		BinTreeNode<T> *p = Find(root, key);
		if (p == NULL)
			return NULL;
		return Parent(root, p);
	}
protected:
	bool Equal(BinTreeNode<T> *t1,BinTreeNode<T> *t2)
	{
		if (t1 == NULL && t2 == NULL)
			return true;
		else if ((t1 != NULL && t2 != NULL)
			&& (t1->data == t2->data)
			&& Equal(t1->left, t2->left)
			&& Equal(t1->right, t2->right))
			return true;
		return false;


	}
	void ConvertList_InOrder(queue<BinTreeNode<T> *> &q, BinTreeNode<T> *t)
	{
		if (t != NULL)
		{
			ConvertList_InOrder(q,t->left);
			//先应用一个队列把前序遍历结点的地址存放
			q.push(t);
			ConvertList_InOrder(q,t->right);
		}
	}
	BinTreeNode<T>* ConvertList(BinTreeNode<T> *t)
	{
		queue<BinTreeNode<T> *> Q;
		//调用上面的函数进行结点地址的获取
		ConvertList_InOrder(Q, t);
		BinTreeNode<T> *head=NULL,*p=NULL,*s;//定义链表的头,p指向头,s指向新出来的结点
		if (!Q.empty())//先让头结点等于第一个出队的结点
		{
			head = Q.front();
			Q.pop();
			head->left = NULL;
			p = head;
		}
		while (!Q.empty())//如果队列不空即还有元素
		{
			s = Q.front();
			Q.pop();
			p->right = s;//rigt相当于链表的next
			s->left = p;//left相当于链表的pre
			p = s;//p移到s
		}
		p->right = NULL;
		return head;
	}
	BinTreeNode<T>* CreateBinTree_VLR_LVR(const char *vlr, const char *lvr, int n)
	{
		if (n == 0)
			return NULL;
		int k = 0;
		while (vlr[0] != lvr[k])
			k++;

		BinTreeNode<T> *t = new BinTreeNode<T>(vlr[0]);
		t->left = CreateBinTree_VLR_LVR(vlr+1,lvr,k);
		t->right = CreateBinTree_VLR_LVR(vlr+k+1,lvr+k+1,n-k-1);
		return t;
	}
	int Weight(BinTreeNode<T> *t)const
	{
		if (t == NULL)
			return 0;
		deque<BinTreeNode<T> *> Q1, Q2;

		Q1.push_back(t);
		int max_weight = 1;
		int tmp_weight = 0;
		BinTreeNode<T> *p;
		while (!Q1.empty())
		{
			while (!Q1.empty())
			{
				p = Q1.front();
				Q1.pop_front();
				if (p->left != NULL)
					Q2.push_back(p->left);
				if (p->right != NULL)
					Q2.push_back(p->right);
			}
			tmp_weight = Q2.size();
			if (tmp_weight > max_weight)
			max_weight = tmp_weight;
			Q1 = Q2;
			Q2.clear();
		}
		return max_weight;
	}
	int LeafSize(BinTreeNode<T> *t)const
	{
		if (t == NULL)
			return 0;
		if (t->left == NULL && t->right == NULL)
			return 1;
		else
			return LeafSize(t->right) + LeafSize(t->right);

	}
	int size(BinTreeNode<T> *t )
	{
		if (t == NULL)
			return 0;
		else
			return size(t->left) + size(t->right) + 1;
	}
	int height(BinTreeNode<T> *root)
	{
		if (root == NULL)
			return 0;
		else
		{
			int m = height(root->left);
			int n = height(root->right);
			return (m > n ? m : n) + 1;
		}
	}
	BinTreeNode<T>* CommonParent(BinTreeNode<T>*t, BinTreeNode<T> *x, BinTreeNode<T> *y)
	{
		if (t == NULL)
			return NULL;
		if (IsInTree(x, y->data))return x;
		if (IsInTree(y, x->data))return y;
		BinTreeNode<T> *left, *right, *another_left, *another_right;
		left = IsInTree(t->left, x->data);
		right = IsInTree(t->right, y->data);
		another_left = IsInTree(t->left, y->data);
		another_right = IsInTree(t->right, x->data);

		if ((left&&right) || (another_right&&another_left))
			return t;
		else if (left&&another_left)
			return CommonParent(t->left, x, y);
		else if (right &&another_right)
			return CommonParent(t->right, x, y);
		else
			return NULL;
	}
	BinTreeNode<T>* Find(BinTreeNode<T> *t, const T &key)
	{
		if (t == NULL)
			return NULL;
		if (t->data == key)
			return t;
		BinTreeNode<T> *p = Find(t->left, key);
		if (p != NULL)
			return p;
		p = Find(t->right, key);
		return p;
	}
	BinTreeNode<T>*Parent(BinTreeNode<T> *t,BinTreeNode<T> *p)
	{
		if (t == NULL||p==t)
			return NULL;
		if (t->left == p || t->right == p)
			return t;
		else
		{
			BinTreeNode<T> *tmp = Parent(t->left,p);
			if (tmp != NULL)
				return tmp;
			return Parent(t->right, p);
		}
	}
	BinTreeNode<T>* IsInTree(BinTreeNode<T> *t, const T &key)
	{
		BinTreeNode<T>*p = Find(t, key);
		if (p != NULL)
			return p;
		else
			return NULL;
	}
	void SwapLeftRightChild(BinTreeNode<T> *&t)
	{
		if (t == NULL || (t->left == NULL && t->right == NULL))
			return;
		BinTreeNode<T> *ptmp = t->left;
		t->left = t->right;
		t->right = ptmp;
		SwapLeftRightChild(t->left);
		SwapLeftRightChild(t->right);
	}
	//////////////////////////////////////////////////////////////////////////
	void Non_Recursive_PreOrder(BinTreeNode<T> *t)const
	{
		
		if (t != NULL)
		{
			stack<BinTreeNode<T> *> s;
			s.push(t);
			BinTreeNode<T> *p;
			while (!s.empty())
			{
				p = s.top();
				s.pop();
				cout << p->data << " ";
				if (p->right != NULL)
					s.push(p->right);
				if (p->left != NULL)
					s.push(p->left);
			}
		}
	}
	void Non_Recursive_InOrder(BinTreeNode<T> *t)const
	{
		stack<BinTreeNode<T> *>s;
		BinTreeNode<T> *temp = t;
		while (temp || !s.empty())
		{
			while (temp)  //有右边就要右边左子树入栈
			{
				s.push(temp);
				temp = temp->left;
			}
			temp = s.top();
			cout << temp->data << " ";
			s.pop();
			temp = temp->right;
		}
	}
	void Non_Recursive_PostOrder(BinTreeNode<T> *t)const
	{
		stack<BinTreeNode<T> *>s;
		BinTreeNode<T> *temp = root, *pre = NULL;
		while (temp || !s.empty())
		{
			while (temp)
			{
				s.push(temp);
				temp = temp->left;
			}
			temp = s.top();
			if (!temp->right || temp->right == pre)//判断无右边
			{
				cout << temp->data << " ";
				s.pop();
				pre = temp;
				temp = NULL;
			}
			else
				temp = temp->right;
		}
	}
	///////////////////////////////////////////////////////////////////////////
	void LeveLOrder(BinTreeNode<T> *t)const
	{
		if (t != NULL)
		{
			queue<BinTreeNode<T>*> Q;
			BinTreeNode<T> *p;
			Q.push(t);
			while (!Q.empty())
			{
				p = Q.front();
				Q.pop();
				cout << p->data << " ";
				if (p->left != NULL)
					Q.push(p->left);
				if (p->right != NULL)
					Q.push(p->right);
			}
		}
	}
	void PreOrder(BinTreeNode<T> *t)const
	{
		if (t != NULL)
		{
			cout << t->data << " ";
			PreOrder(t->left);
			PreOrder(t->right);
		}
	}
	void InOrder(BinTreeNode<T> *t)const
	{
		if (t != NULL)
		{
			InOrder(t->left);
			cout << t->data << " ";
			InOrder(t->right);
		}
	}
	void PostOrder(BinTreeNode<T> *t)const
	{
		if (t != NULL)
		{
			PostOrder(t->left);
			PostOrder(t->right);
			cout << t->data << " ";
		}
	}
	void CreateBinTree(BinTreeNode<T> *&t, const T *&str)
	{
		if (*str == flag || *str == '\0')
		{
			t = NULL;
		}
		else
		{
			t = new BinTreeNode<T>(*str);
			CreateBinTree(t->left, ++str);
			CreateBinTree(t->right, ++str);
		}
	}
private:
	T flag;
	BinTreeNode<T>* root;
};
#endif // ! _BINARYTREE_h

测试

#include"BinaryTree.h"
#include<stdio.h>
int main()
{
	const char *VLR = "ABCDEFGH";
	const char *LVR = "CBEDFAGH";
	const char *LRV = "CEFDBHGA";

	BinaryTree<char> bt;
	bt.CreateBinTree_VLR_LVR(VLR, LVR);

	//BinTreeNode<char>*head = bt.ConvertList();
	/*BinaryTree<char> bt1('#');
	const char *str = "ABC##DE##F##G#H##";
	bt1.CreateBinTree(str);
	bool flag = bt.Equal(bt1);
	cout << flag << endl;*/
	BinaryTree<char> bt1('#');
	const char *str = "BC##DE##F##";
	bt1.CreateBinTree(str);
	bool flag = bt.Equal_Is_Subtree(bt1);
	cout << flag << endl;
}
/*int main()
{
	BinaryTree<char> bt('#');
	const char *str = "ABC##DE##F##G#H##";
	bt.CreateBinTree(str);
	//采用递归方法
	bt.PreOrder();    cout << endl;//前序遍历
	bt.InOrder();     cout << endl;//中序遍历
	bt.PostOrder();   cout << endl;//后序遍历
    //采用非递归方法
	bt.Non_Recursive_PreOrder();    cout << endl;//前序遍历
	bt.Non_Recursive_InOrder();     cout << endl;//中序遍历
	bt.Non_Recursive_PostOrder();   cout << endl;//后序遍历
	bt.SwapLeftRightChild();
	bt.PostOrder(); cout << endl;
	BinTreeNode<char>*pt = bt.CommonParent('E','G');
	cout << "size:" << bt.size() << endl;
	cout << "height:" << bt.height() << endl;
	cout << "LeafSize:" << bt.LeafSize() << endl;
	cout << "Weight:" << bt.Weight() << endl;
	return 0;
}*/

猜你喜欢

转载自blog.csdn.net/zzb2019/article/details/81565392