1. 程式人生 > >【面試筆試】二叉樹相關操作

【面試筆試】二叉樹相關操作

// 二叉樹
// 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;
	}
}