简单的几道算法题_About Binary Tree

存着 以免下次换电脑找不到,哈哈


#include<iostream>
#include<list>
using namespace std;

struct BinaryTreeNode
{
	int m_nValue;
	int m_nLeftMaxLength;  //存放的是左边最长叶子距离
	int m_nRigthMaxLength;
	BinaryTreeNode* m_pLeft;
	BinaryTreeNode* m_pRight;
};

//以前序和中序序列构建二叉树
BinaryTreeNode* ConstructBinaryTree(int preOrder[],int startPreOrder,int endPreOrder,int inOrder[],int startInOrder,int endInOrder)
{
	BinaryTreeNode* pRoot = new BinaryTreeNode();
	pRoot->m_nValue = preOrder[startPreOrder];
	pRoot->m_pRight = pRoot->m_pLeft = NULL;
	

	if(startPreOrder == endPreOrder)
	{
		if(startInOrder == endInOrder && preOrder[startPreOrder] == inOrder[startInOrder])
			return pRoot;
		else
			//cout<<"wrong"<<endl;
			throw std::exception("error!");
	}

	bool flag = false;
	for(int i = startInOrder; i <= endInOrder; ++i)
	{
		if(inOrder[i] == pRoot->m_nValue)
		{
			flag = true;
			break;
		}
	}

	if(flag)
	{
		int leftLength = i - startInOrder;

		if(leftLength > 0)
			pRoot->m_pLeft = ConstructBinaryTree(preOrder,startPreOrder+1,startPreOrder + leftLength,inOrder,startInOrder,startInOrder + leftLength-1);
		
		if(leftLength < endInOrder-startInOrder)
			pRoot->m_pRight = ConstructBinaryTree(preOrder,startPreOrder+leftLength+1,endPreOrder,inOrder,startInOrder+ leftLength+1,endInOrder );

		return pRoot;
	
	}
	else
		throw std::exception("error!");
		//return NULL;
	
}

BinaryTreeNode* ConstructBinaryTree(int preOrder[],int inOrder[],int length)
{
	if(preOrder == NULL || inOrder == NULL || length <= 0)
		return NULL;

	BinaryTreeNode *pRoot = ConstructBinaryTree(preOrder,0,length-1,inOrder,0,length-1);
	return pRoot;

}

//释放二叉树
void DestroyBinaryTree(BinaryTreeNode *pRoot)
{
	if(pRoot == NULL)
		return;

	DestroyBinaryTree(pRoot->m_pLeft);
	DestroyBinaryTree(pRoot->m_pRight);
	delete pRoot;
	pRoot = NULL;
}

//打印二叉树
void PrintLastOrder(BinaryTreeNode* root)
{
	if(root == NULL)
		return;
	if(root->m_pLeft)
		PrintLastOrder(root->m_pLeft);
	if(root->m_pRight)
		PrintLastOrder(root->m_pRight);
	cout<<root->m_nValue<<" ";
}

void PrintPreOrder(BinaryTreeNode* root)
{
	if(root == NULL)
		return;
	cout<<root->m_nValue<<" ";
	if(root->m_pLeft)
		PrintPreOrder(root->m_pLeft);
	if(root->m_pRight)
		PrintPreOrder(root->m_pRight);
	
}

void PrintInOrder(BinaryTreeNode* root)
{
	if(root == NULL)
		return;
	
	if(root->m_pLeft)
		PrintInOrder(root->m_pLeft);
	cout<<root->m_nValue<<" ";
	if(root->m_pRight)
		PrintInOrder(root->m_pRight);
	
}

//寻找二叉搜索树的两个结点的最近公共祖先
BinaryTreeNode* FindLastCommandFather_binaryResearchTree(BinaryTreeNode* pRoot, int n,int m)
{
	if(pRoot == NULL)
		return NULL;
	if(pRoot->m_nValue == n || pRoot->m_nValue == m)
		return pRoot;

	int min = n;
	int max = m;
	if(m < min)
	{
		min = m;
		max = n;
	}
	if(pRoot->m_nValue < min)
		return FindLastCommandFather_binaryResearchTree(pRoot->m_pRight,n,m);
	else if(pRoot->m_nValue > max)
		return FindLastCommandFather_binaryResearchTree(pRoot->m_pLeft,n,m);
	else
		return pRoot;

}

//寻找二叉树中两个结点间的最大差距。以边为单位衡量
int maxLength = 0;
int MaxPath(BinaryTreeNode* pRoot)
{
	if(pRoot == NULL)
		return 0;

	if(pRoot->m_pLeft == NULL)
		pRoot->m_nLeftMaxLength = 0;
	if(pRoot->m_pRight == NULL)
		pRoot->m_nRigthMaxLength = 0;

//	int tempLeft = 0; //左边根到叶子的最长路径长度

	//这里计算pRoot的左子树的最长路径长度
	if(pRoot->m_pLeft != NULL)
	{
		MaxPath(pRoot->m_pLeft);
		if(pRoot->m_pLeft->m_nLeftMaxLength > pRoot->m_pLeft->m_nRigthMaxLength)
			pRoot->m_nLeftMaxLength = pRoot->m_pLeft->m_nLeftMaxLength + 1;
		else
			pRoot->m_nLeftMaxLength = pRoot->m_pLeft->m_nRigthMaxLength + 1;

	}

//	int tempRight = 0;
	if(pRoot->m_pRight != NULL)
	{
		MaxPath(pRoot->m_pRight);
		if(pRoot->m_pRight->m_nLeftMaxLength > pRoot->m_pRight->m_nRigthMaxLength)
			pRoot->m_nRigthMaxLength = pRoot->m_pRight->m_nLeftMaxLength + 1;
		else
			pRoot->m_nRigthMaxLength = pRoot->m_pRight->m_nRigthMaxLength + 1;
	}

	if(maxLength < pRoot->m_nLeftMaxLength + pRoot->m_nRigthMaxLength )
		maxLength = pRoot->m_nLeftMaxLength + pRoot->m_nRigthMaxLength ;

	return maxLength;

}

//打印从根到叶子结点路径和为n的值
void FindPathofValueN(BinaryTreeNode *pRoot,unsigned int n,int curSum,list<int> &path)
{
	path.push_back(pRoot->m_nValue);
	curSum += pRoot->m_nValue;

	if(pRoot->m_pLeft == NULL && pRoot->m_pRight == NULL)
	{
		if(curSum == n)
		{
			for(list<int>::iterator iter = path.begin();iter != path.end();iter++)
				cout<<*iter<<" ";
			cout<<endl;
			
		}
		path.pop_back();
	}
	if(pRoot->m_pLeft != NULL)
		FindPathofValueN(pRoot->m_pLeft,n,curSum,path);
	if(pRoot->m_pRight != NULL)
		FindPathofValueN(pRoot->m_pRight,n,curSum,path);

}
void FindPathofValueN(BinaryTreeNode *pRoot,unsigned int n)
{
	if(pRoot == NULL)
		return;
	list<int> path;
	int curSum = 0;
	FindPathofValueN(pRoot,n,curSum,path);
}

//树A是否树B的子树
bool IsEqualTree(BinaryTreeNode *pRoot1,BinaryTreeNode *pRoot2)
{
	if(pRoot1 == NULL && pRoot2 == NULL)
		return true;
	if(pRoot1 != NULL && pRoot2 != NULL && pRoot1->m_nValue == pRoot2->m_nValue)
	{
		return IsEqualTree(pRoot1->m_pLeft,pRoot2->m_pLeft) && IsEqualTree(pRoot1->m_pRight,pRoot2->m_pRight);
	}
	else
		return false;
}
bool IsSubTree(BinaryTreeNode *pRoot,BinaryTreeNode *pSubRoot)
{
	if(pRoot == NULL && pSubRoot == NULL)
		return true;
	if(pRoot == NULL && pSubRoot != NULL || pRoot != NULL && pSubRoot == NULL)
		return false;

	BinaryTreeNode *pNode = pRoot;

	bool flag = IsEqualTree(pNode,pSubRoot);

	if(pNode->m_pLeft != NULL && !flag)
	{
		flag = IsSubTree(pNode->m_pLeft,pSubRoot);
	//	pNode = pNode->m_pLeft;
	}

	if(pNode->m_pRight != NULL && !flag)
	{
		flag = IsSubTree(pNode->m_pRight,pSubRoot);
	//	pNode = pNode->m_pRight;
	}
	return flag;
}

//把二叉搜索树转换为双向链表
void ConvertBinarySearchTreeToDoubleList(BinaryTreeNode *pRoot,BinaryTreeNode **lastNode)
{
	if(pRoot->m_pLeft != NULL)
		ConvertBinarySearchTreeToDoubleList(pRoot->m_pLeft,lastNode);

	if( *lastNode != NULL)
		(*lastNode)->m_pRight = pRoot;

	pRoot->m_pLeft = (*lastNode);
	*lastNode = pRoot;

	if(pRoot->m_pRight != NULL)
		ConvertBinarySearchTreeToDoubleList(pRoot->m_pRight,lastNode);
}
BinaryTreeNode* ConvertBinarySearchTreeToDoubleList(BinaryTreeNode *pRoot)
{
	if(pRoot == NULL)
		return NULL;

	BinaryTreeNode *lastNode = NULL;
	ConvertBinarySearchTreeToDoubleList(pRoot,&lastNode);
	lastNode->m_pRight = NULL;
	BinaryTreeNode *pDoubleListHead = lastNode;
	while(pDoubleListHead->m_pLeft != NULL)
		pDoubleListHead = pDoubleListHead->m_pLeft;

	return pDoubleListHead;

}

//寻找二叉树中两个结点的值差值最大的绝对值
void Find(BinaryTreeNode *pRoot,int &min,int &max)
{

    int temp = pRoot->m_nValue;
    if(temp < min)
        min = temp;
    if(temp > max)
        max = temp;
    if(pRoot->m_pLeft != NULL)
    {
        Find(pRoot->m_pLeft,min,max);
    }

      if(pRoot->m_pRight != NULL)
    {
        Find(pRoot->m_pRight,min,max);
    }

}

int Find(BinaryTreeNode *pRoot)
{
     if (pRoot == NULL)
        return -1;

    int min = 32768;  //最大的整数
    int max = -32767;  //最小的整数
    Find(pRoot,min,max);
    return max - min;
}



void main()
{
	/*
	int pre[] = {10};
	int in[] = {10};
	int len = sizeof(pre)/sizeof(int);
	BinaryTreeNode* root = ConstructBinaryTree(pre,in,len);
	PrintPreOrder(root);
	cout<<endl;
	PrintInOrder(root);
	cout<<endl;
	PrintLastOrder(root);
	cout<<endl;

	BinaryTreeNode* node = FindLastCommandFather_binaryResearchTree(root,15,10);
	cout<<node->m_nValue<<endl;

	cout<<"max length of binary tree is: "<<MaxPath(root)<<endl;

	FindPathofValueN(root,14);
*/
	int pre1[] = {-1,9};
	int in1[] = {-1,9};
//	int pre2[] = {7};
//	int in2[] = {7};
	int len1 = sizeof(pre1)/sizeof(int);
//	int len2 = sizeof(pre2)/sizeof(int);
	BinaryTreeNode* root1 = ConstructBinaryTree(pre1,in1,len1);
	//BinaryTreeNode* root2 = ConstructBinaryTree(pre2,in2,len2);
	PrintPreOrder(root1);
	cout<<endl;
	PrintInOrder(root1);
	cout<<endl;
	PrintLastOrder(root1);
	cout<<endl;
    root1 = NULL;
	cout<<Find(root1)<<endl;
	DestroyBinaryTree(root1);
//	root1 = NULL;
//	root2 = NULL;
	/*
	if(IsSubTree(root1,root2))
		cout<<"Yes"<<endl;
	else
		cout<<"NO"<<endl;
		*/
/*
	BinaryTreeNode* p = ConvertBinarySearchTreeToDoubleList(root);
	while(p != NULL)
	{
		cout<<p->m_nValue<<" ";
		p = p->m_pRight;
	}
	cout<<endl;

*/

}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值