简单的几道算法题_About Binary Tree

本文详细介绍了二叉树的各种操作实现方法,包括构建、遍历、查找、转换等,并提供了完整的C++代码示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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


#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;

*/

}


内容概要:本文详细介绍了扫描单分子定位显微镜(scanSMLM)技术及其在三维超分辨体积成像中的应用。scanSMLM通过电调透镜(ETL)实现快速轴向扫描,结合4f检测系统将不同焦平面的荧光信号聚焦到固定成像面,从而实现快速、大视场的三维超分辨成像。文章不仅涵盖了系统硬件的设计与实现,还提供了详细的软件代码实现,包括ETL控制、3D样本模拟、体积扫描、单分子定位、3D重建和分子聚类分析等功能。此外,文章还比较了循环扫描与常规扫描模式,展示了前者在光漂白效应上的优势,并通过荧光珠校准、肌动蛋白丝、线粒体网络和流感A病毒血凝素(HA)蛋白聚类的三维成像实验,验证了系统的性能和应用潜力。最后,文章深入探讨了HA蛋白聚类与病毒感染的关系,模拟了24小时内HA聚类的动态变化,提供了从分子到细胞尺度的多尺度分析能力。 适合人群:具备生物学、物理学或工程学背景,对超分辨显微成像技术感兴趣的科研人员,尤其是从事细胞生物学、病毒学或光学成像研究的科学家和技术人员。 使用场景及目标:①理解和掌握scanSMLM技术的工作原理及其在三维超分辨成像中的应用;②学习如何通过Python代码实现完整的scanSMLM系统,包括硬件控制、图像采集、3D重建和数据分析;③应用于单分子水平研究细胞内结构和动态过程,如病毒入侵机制、蛋白质聚类等。 其他说明:本文提供的代码不仅实现了scanSMLM系统的完整工作流程,还涵盖了多种超分辨成像技术的模拟和比较,如STED、GSDIM等。此外,文章还强调了系统在硬件改动小、成像速度快等方面的优势,为研究人员提供了从理论到实践的全面指导。
内容概要:本文详细介绍了基于Seggiani提出的渣层计算模型,针对Prenflo气流床气化炉中炉渣的积累和流动进行了模拟。模型不仅集成了三维代码以提供气化炉内部的温度和浓度分布,还探讨了操作条件变化对炉渣行为的影响。文章通过Python代码实现了模型的核心功能,包括炉渣粘度模型、流动速率计算、厚度更新、与三维模型的集成以及可视化展示。此外,还扩展了模型以考虑炉渣组成对特性的影响,并引入了Bingham流体模型,更精确地描述了含未溶解颗粒的熔渣流动。最后,通过实例展示了氧气-蒸汽流量增加2%时的动态响应,分析了温度、流动特性和渣层分布的变化。 适合人群:从事煤气化技术研究的专业人士、化工过程模拟工程师、以及对工业气化炉操作优化感兴趣的科研人员。 使用场景及目标:①评估不同操作条件下气化炉内炉渣的行为变化;②预测并优化气化炉的操作参数(如温度、氧煤比等),以防止炉渣堵塞;③为工业气化炉的设计和操作提供理论支持和技术指导。 其他说明:该模型的实现基于理论公式和经验数据,为确保模型准确性,实际应用中需要根据具体气化炉的数据进行参数校准。模型还考虑了多个物理场的耦合,包括质量、动量和能量守恒方程,能够模拟不同操作条件下的渣层演变。此外,提供了稳态求解器和动态模拟工具,可用于扰动测试和工业应用案例分析。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值