【面试笔试】二叉树相关操作

// 二叉树
// 2015.08.07
//@ author :braveji
/** 二叉树的功能
** 1 建立二叉树 销毁二叉树
** 2 二叉树的遍历:前、中、后,层,分层;递归、非递归;
** 3 二叉树的高度、宽度、叶子节点个数
** 4 将二叉搜索树转换为双链表
** 5 二叉树的镜像
** 6 找出和为指定值的所有路径(后序遍历)
** 7 是否是平衡二叉树(左子树的深度pk右子数的深度)
** 7 相距最远的两个节点的距离(左子树深度+右子树的深度)
** 8 给定两个节点求其最近公共父节点
** 9 判断是否是完全二叉树?
** 10 根据前序和中序遍历重构二叉树
**/

#include <vector>
#include <string>
#include <iostream>
#include <fstream>
#include <queue>
#include <stack>

using namespace std;

//difine Btree
struct Btree
{
	int m_data;
	Btree * m_lchild;
	Btree * m_rchild;
};

// initialization

Btree * initBtree()
{
	return NULL;
}

// build Btree
const int edge = 65535;
fstream fin("init.txt");
int data;
void buildBtree(Btree* &root,fstream &fin)
{
	if(fin >> data)
	{
		//preorder build Btree
		if (data == edge)
		{
			root = NULL;
		}
		else 
		{
			root = new Btree;
			root->m_data = data;
			root->m_lchild = NULL;
			root->m_rchild = NULL;

			buildBtree(root->m_lchild,fin);
			buildBtree(root->m_rchild,fin);
		}
	}
}
Btree * buildBtree()
{
	Btree * root = initBtree();
	buildBtree(root,fin);
	fin.close();
	return root;
}

//traverse tree
//1 preorder recursion
void preOrderBtree(Btree * root,vector<int> & vectorTemp)
{
	if (root)
	{
		cout<<root->m_data<<" ";
		vectorTemp.push_back(root->m_data);
		preOrderBtree(root->m_lchild,vectorTemp);
		preOrderBtree(root->m_rchild,vectorTemp);
	}
}

vector<int> preOrderBtree(Btree * root)
{
// 	if (root)
// 	{
// 		cout<<root->m_data<<" ";
// 		preOrderBtree(root->m_lchild);
// 		preOrderBtree(root->m_rchild);
// 	}
	vector<int> vectorTemp;
	preOrderBtree(root,vectorTemp);
	return vectorTemp;
}
//2 inorder recursion
void inOrderBtree(Btree * root,vector<int> & vectorTemp)
{
	if (root)
	{
		inOrderBtree(root->m_lchild,vectorTemp);
		cout<<root->m_data<<" ";
		vectorTemp.push_back(root->m_data);
		inOrderBtree(root->m_rchild,vectorTemp);
	}
}

vector<int> inOrderBtree(Btree * root)
{
// 	if (root)
// 	{
// 		inOrderBtree(root->m_lchild);
// 		cout<<root->m_data<<" ";
// 		inOrderBtree(root->m_rchild);
// 	}
	vector<int> vectorTemp;
	inOrderBtree(root,vectorTemp);
	return vectorTemp;
}

//3 postorder recursion
void postOrderBtree(Btree *root)
{
	if (root)
	{
		postOrderBtree(root->m_lchild);
		postOrderBtree(root->m_rchild);
		cout<<root->m_data<<" ";
	}
}

// 4 level order
void leverOrderBtree(Btree * root)
{
	queue<Btree*> que;
	if (root)
	{
		que.push(root);
		while(que.size())
		{
			Btree * temp = que.front();
			cout<<temp->m_data<<ends;
			que.pop();
			if (temp->m_lchild) que.push(temp->m_lchild);
			if (temp->m_rchild) que.push(temp->m_rchild);
		}
		cout<<endl;
	}
}

// multi lever order
void multiLeverOrderBtree(Btree * root)
{
	queue<Btree*> que;
	int nextLever=0,toBePrinted=1;//只有上一层遍历完才知道下一层总共有多少个结点需要遍历
	int i=1;
	if (root)
	{
		que.push(root);
		//cout<<"第"<<i<<"层:";
		while(que.size())
		{
			Btree * temp = que.front();
			cout<<temp->m_data<<ends;
			que.pop();
			toBePrinted--;
			if (temp->m_lchild) 
			{
				que.push(temp->m_lchild);
				nextLever++;
			}
			if (temp->m_rchild) 
			{
				que.push(temp->m_rchild);
				nextLever++;
			}
			if (!toBePrinted)
			{
				toBePrinted = nextLever;
				nextLever =0;
				++i;
				cout<<endl;
				//cout<<"第"<<i+1<<"层:";
			}
		}
	}
}

//preorder nonrecursion
void preOrderNonrecurion(Btree * root)
{
	stack<Btree *> stackTemp;
	while(root || stackTemp.size())
	{
		if (root)
		{
			cout<<root->m_data<<ends;
			stackTemp.push(root);
			root = root->m_lchild;
		}
		else
		{
			Btree * temp = stackTemp.top();
			stackTemp.pop();
			root = temp->m_rchild;
		}
	}
	cout<<endl;
}

//inorder nonrecursion
void inOrderNonrecursion(Btree * root)
{
	stack<Btree *> stackTemp;
	while(root || stackTemp.size())
	{
		if (root)
		{
			stackTemp.push(root);
			root = root->m_lchild;
		}
		else
		{
			Btree * temp = stackTemp.top();
			stackTemp.pop();
			cout<<temp->m_data<<ends;
			root = temp->m_rchild;
		}
	}
	cout<<endl;
}

//postorder unrecursion
void postOrderRecursion(Btree * root)
{
	stack<Btree *> stackTemp;
	if (root)
		stackTemp.push(root);
	Btree * cur;
	Btree * prev = NULL;
	while(stackTemp.size())
	{
		cur = stackTemp.top();
		if ((!cur->m_lchild && !cur->m_rchild)||
			(prev &&(prev == cur->m_lchild || prev == cur->m_rchild)))
		{
			cout<<cur->m_data<<ends;
			stackTemp.pop();
			prev = cur;
		}
		else
		{
			if (cur->m_rchild)
				stackTemp.push(cur->m_rchild);
			if (cur->m_lchild)
				stackTemp.push(cur->m_lchild);
		}
	}
	cout<<endl;
}

//deepth 
int deepthBtree(Btree * root)
{
	if (!root)
		return 0;
	int i = deepthBtree(root->m_lchild);
	int j = deepthBtree(root->m_rchild);

	return i>j?i+1:j+1;
}

//leaf number
int leafNumber(Btree * root)
{
	//traverse + leaf
	int leafNum=0;
	stack<Btree *> stackTemp;
	while(root || stackTemp.size())
	{
		while (root)
		{
			if (!root->m_lchild && !root->m_rchild)
				leafNum++;
			stackTemp.push(root);
			root = root->m_lchild;
		}
		if(stackTemp.size())
		{
			Btree * temp = stackTemp.top();
			stackTemp.pop();
			root = temp->m_rchild;
		}
	}
	return leafNum;
}

//width BTree
int widthBtree(Btree * root)
{
	int maxWidth=0;
	int toBeDone =1;
	int count =0;
	queue<Btree*> que;
	if(root)
		que.push(root);
	while(que.size())
	{
		Btree * temp = que.front();
		que.pop();
		if (temp->m_lchild)
		{
			que.push(temp->m_lchild);
			count++;
		}
		if (temp->m_rchild)
		{
			que.push(temp->m_rchild);
			count++;
		}
		toBeDone--;
		if (!toBeDone)
		{
			toBeDone = count;
			if (count > maxWidth) 
				maxWidth = count;
			count=0;
		}
	}
	return maxWidth;
}

//i th level  print
void printILevel(Btree * root,int i)
{
	int deep = deepthBtree(root);
	if (i>deep)
	{
		cout<<"error!!打印的行数超过了树的深度!!"<<endl;
		return;
	}
	queue<Btree *> que;
	int toBeDone =1;
	int nextLevelNum =0;
	int level = 1;
	if (root)
		que.push(root);
	cout<<"只打印第"<<i<<"层: ";
	while(que.size())
	{
		Btree * temp = que.front();
		if (i==level)
			cout<<temp->m_data<<ends;
		if (i+1==level)
			break;
		que.pop();
		if (temp->m_lchild)
		{
			que.push(temp->m_lchild);
			nextLevelNum++;
		}
		if (temp->m_rchild)
		{
			que.push(temp->m_rchild);
			nextLevelNum++;
		}
		toBeDone--;
		if (!toBeDone)
		{
			toBeDone = nextLevelNum;
			nextLevelNum =0;
			level++;
		}
	}
	cout<<endl;
}

//mirror tree
Btree* mirrorBtree(Btree * root)
{
	if (root)
	{
		Btree * temp = root->m_lchild;
		root->m_lchild = root->m_rchild;
		root->m_rchild = temp;
		if (root->m_lchild) mirrorBtree(root->m_lchild);
		if (root->m_rchild) mirrorBtree(root->m_rchild);
	}
	return root;
}

//deepth nonrecursion
int deepthNonRecursion(Btree * root)
{
	//levle order
	int toBeDone =1;
	int nextLevel =0;
	int deep =0;
	queue<Btree*> que;
	if (root)
		que.push(root);
	while(que.size())
	{
		Btree * temp = que.front();
		que.pop();
		if (temp->m_lchild)
		{
			que.push(temp->m_lchild);
			nextLevel++;
		}
		if (temp->m_rchild)
		{
			que.push(temp->m_rchild);
			nextLevel++;
		}
		toBeDone--;
		if (!toBeDone)
		{
			deep++;
			toBeDone = nextLevel;
			nextLevel =0;
		}
	}
	return deep;
}

//balanced Btree
//bool isBalancedBtree(Btree * root)
//{
//	if (!root)
//		return true;
//	int i = deepthBtree(root->m_lchild);
//	int j = deepthBtree(root->m_rchild);
//	if (abs(i-j)>1)
//		return false;
//	else
//		return isBalancedBtree(root->m_lchild) && isBalancedBtree(root->m_rchild);
//}

//测试集1:平衡树  10 6 3 2 65535 65535 4 65535 65535 8 7 65535 65535 9 65535 65535 20 15  12 65535 65535 17 65535 65535 25 22 65535 65535 30 65535 65535
//测试集2:非平衡  10 6 3 2 65535 65535 4 65535 65535 8 7 65535 65535 9 65535 65535 20 65535 65535
bool isBalancedBtree(Btree* root)
{
	stack<Btree*> stackTemp;
	while(root || stackTemp.size())
	{
		while(root)
		{
			int i= deepthBtree(root->m_lchild);
			int j = deepthBtree(root->m_rchild);
			if (abs(i-j)>1)
				return false;
			//if (root->m_lchild)
			//	stackTemp.push(root->m_lchild);//错误原因:加了条件判断
			stackTemp.push(root);
			root = root->m_lchild;
		}
		if (stackTemp.size())
		{
			Btree * temp = stackTemp.top();
			stackTemp.pop();
			root = temp->m_rchild;
		}
	}
	return true;
}

//lowest parent  Binary Search Tree
Btree * lowestParent(Btree * root,Btree* node1,Btree* node2)
{
	if ((root->m_data >= node1->m_data && root->m_data <= node2->m_data) ||
		(root->m_data <= node1->m_data && root->m_data >= node2->m_data))
	{
		return root;
	}
	if (root->m_data < node1->m_data && root->m_data < node2->m_data)
		return lowestParent(root->m_rchild,node1,node2);
	else return lowestParent(root->m_lchild,node1,node2); 
}

//10 6 3 2 65535 65535 4 65535 65535 8 7 65535 65535 9 65535 65535 20 15  12 65535 65535 17 65535 65535 25 22 65535 65535 30 65535 65535
//convert to doublelinklist
// 10 6 3  65535 65535 8 65535 65535  20 15   65535 65535  25  65535 65535
void conver2list(Btree* root,Btree * &prev,Btree * &head,Btree * & last)
{//root 没有引用,prev有引用,
	if (root)
	{
		//last = root;
		if (root->m_lchild)
			conver2list(root->m_lchild,prev,head,last);
		root->m_lchild = prev;//修改了root
		if (prev) prev->m_rchild = root;
		prev = root;
		if (!head)
			head = root;

		if (root->m_rchild)
			conver2list(root->m_rchild,prev,head,last);

	}
// 	if (root->m_lchild)
// 		conver2list(root->m_lchild,prev,head);
// 
// 	root->m_lchild = prev;
// 	if (prev) 
// 		prev->m_rchild = root;
// 	prev = root;
// 	if (!head)
// 		head = root;
// 
// 	if (root->m_rchild)
// 		conver2list(root->m_rchild,prev,head);
}

Btree * conver2list(Btree* root)
{
	Btree * prev = NULL;
	Btree * head = NULL;
	Btree * last = NULL;
	//if (root)
		conver2list(root,prev,head,last);
	return head;
}

// convert to list nonconversion
Btree * convert2ListNonrecursion(Btree * root)
{
	//inorder 
	Btree * prev = NULL;
	Btree * head = NULL;
	stack<Btree *> stackTemp;
	while(root || stackTemp.size())
	{
		while(root)
		{
			stackTemp.push(root);
			root = root->m_lchild;
		}
		if (stackTemp.size())
		{
			Btree * curr = stackTemp.top();
			stackTemp.pop();
			curr->m_lchild = prev;
			if (prev) prev->m_rchild = curr;
			prev = curr;
			if (!head) head = curr;

			//if (curr->m_rchild) root = curr->m_rchild;
			root = curr->m_rchild;
		}
	}
	return head;
}

void printConverList(Btree * root)
{
	cout<<"从小到大:"<<ends;
	Btree * temp;
	while(root)
	{
		temp= root;
		cout<<root->m_data<<" ";
		root = root->m_rchild;
	}
	cout<<endl<<"从大到下:"<<ends;
	while(temp)
	{
		cout<<temp->m_data<<" ";
		temp  = temp->m_lchild;
	}
	cout<<endl;
}

//destroy list
void destroyList(Btree * head)
{
	Btree * next = head;
	while(head)
	{
		next = head->m_rchild;
		delete head;
		head = NULL;
		head = next;
	}
}

//和为指定值的所有路径
//指定结点的路径(根到结点的路径)
bool pathToNode(Btree * root,Btree * node,vector<Btree *> & stackTemp)
{
	//preorder
	if (!root)
		return false;
	stackTemp.push_back(root);
	if (root == node)
		return true;

	bool found = pathToNode(root->m_lchild,node,stackTemp);
	if (!found) 
		found = pathToNode(root->m_rchild,node,stackTemp);
	if (!found)
		stackTemp.pop_back();
	return found;
}

//找到值为某一值的结点
Btree * findNodeKey(Btree * root,int num)
{
	//front order
	stack<Btree *> stackTemp;
	while(root || stackTemp.size())
	{
		while(root)
		{
			stackTemp.push(root);
			if (root->m_data == num)
			{
				return root;
			}
			root = root->m_lchild;
		}
		if (stackTemp.size())
		{
			Btree * temp = stackTemp.top();
			stackTemp.pop();
			root = temp->m_rchild;
		}
	}
	return NULL;
}

// 非递归 两个结点的最低公共祖先
Btree* lowestParentNorecursion(Btree * root,Btree * node1,Btree * node2)
{
	vector<Btree *> temp1,temp2;
	pathToNode(root,node1,temp1);
	pathToNode(root,node2,temp2);
	int i= temp1.size();
	int j =temp2.size();
	int k=0;
	Btree * parent= root;
	while(k<i && k<j)
	{
		if (temp2[k] == temp1[k])
		{
			parent = temp1[k];
			k++;
		}
		else break;
	}
	return parent;
}

//叶子节点的所有路径
void pathEqualValue(Btree* root,vector<vector<Btree*>> &vectorTemp,vector<Btree*> &temp)
{
	if (!root)
		return ;
	temp.push_back(root);
	if (!root->m_lchild && !root->m_rchild)
	{
		vectorTemp.push_back(temp);
		temp.pop_back();
// 		root = temp[temp.size()-1]->m_rchild;
// 		pathEqualValue(root,num,vectorTemp,temp);
		return ;
	}
	//if(root->m_lchild)
		pathEqualValue(root->m_lchild,vectorTemp,temp);
	//if (root->m_rchild)
		pathEqualValue(root->m_rchild,vectorTemp,temp);
	temp.pop_back();
// 	if (!temp.size())
// 	{
// 		return ;
// 	}
}

//等于给定值的所有路径
void pathEqualValue(Btree* root,int num,int sum,vector<vector<Btree*>> &vectorTemp,vector<Btree*> &temp)
{
	//preorder
	if (!root)
		return;
	sum+= root->m_data;
	temp.push_back(root);
	if (!root->m_lchild && !root->m_rchild)
	{
		if (sum == num)
		{
			vectorTemp.push_back(temp);
			temp.pop_back();
			sum -= root->m_data;
			return;
		}
	}
	pathEqualValue(root->m_lchild,num,sum,vectorTemp,temp);
	pathEqualValue(root->m_rchild,num,sum,vectorTemp,temp);
	temp.pop_back();
	sum -= root->m_data;
}
void pathEqualValue(Btree* root,int num)
{
	vector<vector<Btree*> > vectorTemp,vectorTemp1;
	vector<Btree*> temp,temp1;

	pathEqualValue(root,vectorTemp,temp);
	cout<<"所有叶子节点的路径:"<<endl;
	for (unsigned i=0;i<vectorTemp.size();++i)
	{
		temp = vectorTemp[i];
		for (unsigned j=0;j<temp.size();++j)
		{
			cout<<temp[j]->m_data<<" ";
		}
		cout<<endl;
	}

	pathEqualValue(root,num,0,vectorTemp1,temp1);
	cout<<"所有值为"<<num<<"的路径:"<<endl;
	for (unsigned i=0;i<vectorTemp1.size();++i)
	{
		temp = vectorTemp1[i];
		for (unsigned j=0;j<temp.size();++j)
		{
			cout<<temp[j]->m_data<<" ";
		}
		cout<<endl;
	}
}

//结点最大距离
int maxLengthBtree(Btree * root)
{
	if (!root)
		return 0;
	int i = deepthBtree(root->m_lchild);
	int j = deepthBtree(root->m_rchild);
	return i+j;
}

//根据前序遍历和中序遍历重构一棵树
Btree * rebuild(vector<int> &preorder,vector<int> &inorder,int preleft,int preright,int inleft,int inright)
{
	if (preright-preleft<0)
	{
		return NULL;
	}
	Btree * root = new Btree;
	root->m_data = preorder[preleft];
	root->m_lchild = NULL;
	root ->m_rchild = NULL;

	int middle =-1;
	for (unsigned i=0;i<inorder.size();++i)
	{
		if (root->m_data == inorder[i])
		{
			middle = i;
			break;
		}
	}

	int d = middle-inleft;

	int preleft1 = preleft +1;
	//int preright1 = middle;
	int preright1 = preleft +d;
	int inleft1 = inleft;
	int inright1 = middle-1;
	root->m_lchild = rebuild(preorder,inorder,preleft1,preright1,inleft1,inright1);

	//int preleft2 = middle+1;
	int preleft2 = preleft +d+1;
	int preright2 = preright;
	int inleft2 = middle+1;
	int inright2 = inright;
	root->m_rchild = rebuild(preorder,inorder,preleft2,preright2,inleft2,inright2);

	return root;
}

Btree * rebuild(vector<int> & preorder,vector<int> & inorder)
{
	int end = preorder.size();
	Btree * root = rebuild(preorder,inorder,0,end-1,0,end-1);
	return root;
}

//判断是否是完全二叉树
bool isCompleteBtree2(Btree * root)
{
	queue<Btree*> queTemp;
	if (root)
		queTemp.push(root);
	while(queTemp.size())
	{
		Btree * temp = queTemp.front();
		queTemp.pop();
		if (temp)
		{
			queTemp.push(temp->m_lchild);
			queTemp.push(temp->m_rchild);
		}
		else
		{
			while(queTemp.size())
			{
				temp = queTemp.front();
				queTemp.pop();
				if (temp)
				{
					return false;
				}
			}
		}
	}
	return true;
}

//是否完全二叉树
bool isCompleteBtree(Btree * root)
{
	queue<Btree*> queueTemp;
	if(root)
		queueTemp.push(root);
	Btree * temp = queueTemp.front();
	while(temp)
	{
		queueTemp.pop();
		queueTemp.push(temp->m_lchild);
		queueTemp.push(temp->m_rchild);
		temp = queueTemp.front();
	}
	while(queueTemp.size())
	{
		temp = queueTemp.front();
		if (temp)
		{
			return false;
		}
		queueTemp.pop();
	}
	return true;
}

//destory Btree
void destroyBtree(Btree * root)
{
	if (root)
	{
		destroyBtree(root->m_lchild);
		destroyBtree(root->m_rchild);
		delete root;
		root = NULL;
	}
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
该资源内项目源码是个人的课程设计、毕业设计,代码都测试ok,都是运行成功后才上传资源,答辩评审平均分达到96分,放心下载使用! ## 项目备注 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用! 2、本项目适合计算机相关专业(如计科、人工智能、通信工程、自动化、电子信息等)的在校学生、老师或者企业员工下载学习,也适合小白学习进阶,当然也可作为毕设项目、课程设计、作业、项目初期立项演示等。 3、如果基础还行,也可在此代码基础上进行修改,以实现其他功能,也可用于毕设、课设、作业等。 下载后请首先打开README.md文件(如有),仅供学习参考, 切勿用于商业用途。 该资源内项目源码是个人的课程设计,代码都测试ok,都是运行成功后才上传资源,答辩评审平均分达到96分,放心下载使用! ## 项目备注 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用! 2、本项目适合计算机相关专业(如计科、人工智能、通信工程、自动化、电子信息等)的在校学生、老师或者企业员工下载学习,也适合小白学习进阶,当然也可作为毕设项目、课程设计、作业、项目初期立项演示等。 3、如果基础还行,也可在此代码基础上进行修改,以实现其他功能,也可用于毕设、课设、作业等。 下载后请首先打开README.md文件(如有),仅供学习参考, 切勿用于商业用途。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值