zoukankan      html  css  js  c++  java
  • 二叉树代码(较全)

    #include <iostream>
    #include <vector>
    #include <list>
    using namespace std;
    
    // 节点结构体
    typedef struct node
    {
    	int 	data;
    	node*	leftChild;
    	node*	rightChild;
    	bool	leftVisited;
    	bool	rightVisited;
    
    	node()
    	{
    		int data		= -1;
    		leftChild		= NULL;
    		rightChild		= NULL;
    		leftVisited		= false;
    		rightVisited	= false;
    	}
    
    }Node, *pNode;
    
    //******************************************************************************
    // Name: CreateChild
    // Desc: 创建子树
    //******************************************************************************
    void CreateChild(Node* &root, vector<int>::iterator &beginIter, 
    				 vector<int>::iterator &endIter)
    {
    	if(beginIter != endIter)
    	{
    		int tempData = *beginIter++;
    		if(tempData != -1)
    		{
    			root = new Node;
    			root->data = tempData;
    			CreateChild(root->leftChild, beginIter, endIter);	// 创建左子树
    			CreateChild(root->rightChild, beginIter, endIter);	// 创建右子树
    		}
    		else
    		{
    			root = NULL;
    		}
    	}
    	else
    	{
    		root = NULL;
    	}
    }
    
    //******************************************************************************
    // Name: CreateTree
    // Desc: 先序扩展序列创建一棵树(先序遍历,空节点用-1标识)
    //******************************************************************************
    Node* CreateTree(Node* root, vector<int> &dataVec)
    {
    	if(dataVec.size() < 1)	return NULL;
    	
    	vector<int>::iterator beginIter = dataVec.begin();
    	vector<int>::iterator endIter	= dataVec.end();
    
    	root = NULL;
    	CreateChild(root, beginIter, endIter);
    	
    	return root;
    }
    
    //******************************************************************************
    // Name: DisplayTree
    // Desc: 二叉显示
    //******************************************************************************
    void DisplayTree(Node* root)
    {
    	if(root != NULL)
    	{
    		cout<<"node:"<<root->data<<" ";
    		if(root->leftChild != NULL)
    		{
    			cout<<"leftChild:"<<root->leftChild->data<<" ";
    		}
    		if(root->rightChild != NULL)
    		{
    			cout<<"rightChild:"<<root->rightChild->data<<" ";
    		}
    		cout<<endl;
    
    		DisplayTree(root->leftChild);
    		DisplayTree(root->rightChild);
    	}
    }
    
    //******************************************************************************
    // Name: FirstVisite
    // Desc: 先根遍历(递归)
    //******************************************************************************
    void FirstVisite(Node* root)
    {
    	if(root != NULL)
    	{
    		cout<<root->data<<" ";
    		FirstVisite(root->leftChild);
    		FirstVisite(root->rightChild);
    	}
    }
    
    //******************************************************************************
    // Name: CenterVisite
    // Desc: 中根遍历(递归)
    //******************************************************************************
    void CenterVisite(Node* root)
    {
    	if(root != NULL)
    	{
    		CenterVisite(root->leftChild);
    		cout<<root->data<<" ";
    		CenterVisite(root->rightChild);
    	}
    }
    
    //******************************************************************************
    // Name: AfterVisite
    // Desc: 后根遍历(递归)
    //******************************************************************************
    void AfterVisite(Node* root)
    {
    	if(root != NULL)
    	{
    		AfterVisite(root->leftChild);
    		AfterVisite(root->rightChild);
    		cout<<root->data<<" ";
    	}
    }
    
    //******************************************************************************
    // Name: ResetTree
    // Desc: 重置二叉树,方便一次遍历
    //******************************************************************************
    void ResetTree(Node* root)
    {
    	if(root != NULL)
    	{
    		root->leftVisited	= false;
    		root->rightVisited	= false;
    		ResetTree(root->leftChild);
    		ResetTree(root->rightChild);
    	}
    }
    
    //******************************************************************************
    // Name: _FirstVisite
    // Desc: 先根遍历(非递归)
    //******************************************************************************
    void _FirstVisite(Node* tree)
    {
    	ResetTree(tree);
    
    	typedef vector<Node*> NodeStack;
    	NodeStack stack;
    	stack.push_back(tree); // 初始化栈
    
    	while (stack.size() > 0)
    	{
    		Node* topNode = stack.back();
    		if (!topNode->leftVisited && !topNode->rightVisited)
    		{
    			cout<<topNode->data<<" ";
    		}
    
    		if (topNode->leftChild != NULL && !topNode->leftVisited)
    		{
    			stack.push_back(topNode->leftChild);
    			topNode->leftVisited = true;
    		}
    		else if (topNode->rightChild != NULL && !topNode->rightVisited)
    		{
    			stack.push_back(topNode->rightChild);
    			topNode->rightVisited = true;
    		} 
    		else
    		{
    			stack.pop_back();
    		}
    	}
    }
    
    //******************************************************************************
    // Name: __FirstVisite
    // Desc: 非递归先根遍历思路二
    //******************************************************************************
    void __FirstVisite(Node* tree)
    {
    	typedef vector<Node*> NodeStack;
    	NodeStack stack;
    	Node *curNode = tree;
    	while(!stack.empty() || curNode != NULL)
    	{
    		while(curNode != NULL)
    		{
    			cout<<curNode->data<<" ";
    			stack.push_back(curNode);
    			curNode = curNode->leftChild;
    		}
    
    		if(!stack.empty())
    		{
    			curNode = stack.back();
    			curNode = curNode->rightChild;
    			stack.pop_back();
    		}
    	}
    }
    
    //******************************************************************************
    // Name: _CenterVisit
    // Desc: 中根遍历(非递归)
    //******************************************************************************
    void _CenterVisite(Node* tree)
    {
    	ResetTree(tree);
    
    	typedef vector<Node*> NodeStack;
    	NodeStack stack;
    	stack.push_back(tree);	//  初始化
    
    	while (stack.size() > 0)
    	{
    		Node* topNode = stack.back();
    		if (topNode->leftVisited && !topNode->rightVisited)
    		{
    			cout<<topNode->data<<" ";
    		}
    
    
    		if (topNode->leftChild != NULL && !topNode->leftVisited)
    		{
    			stack.push_back(topNode->leftChild);
    			topNode->leftVisited = true;
    		}
    		else 
    		{
    			if (topNode->rightChild != NULL && !topNode->rightVisited)
    			{
    				if (topNode->leftChild == NULL && topNode->rightChild != NULL)
    				{
    					cout<<topNode->data<<" ";		// 单边只有右子节点
    				}
    				stack.push_back(topNode->rightChild);
    				topNode->rightVisited = true;
    			} 
    			else
    			{
    				if (topNode->leftChild == NULL && topNode->rightChild == NULL)
    				{
    					cout<<topNode->data<<" ";
    				}
    				stack.pop_back();
    			}
    		}
    	}
    }
    
    //******************************************************************************
    // Name: __CenterVisite
    // Desc: 非递归中根遍历思路二
    //******************************************************************************
    void __CenterVisite(Node* tree)
    {
    	typedef vector<Node*> NodeStack;
    	NodeStack stack;
    
    	Node* curNode = tree;
    	while(!stack.empty() || curNode != NULL)
    	{
    		while(curNode != NULL)
    		{
    			stack.push_back(curNode);
    			curNode = curNode->leftChild;
    		}
    
    		if(!stack.empty())
    		{
    			curNode = stack.back();
    			cout<<curNode->data<<" ";
    			curNode = curNode->rightChild;
    			stack.pop_back();
    		}
    	}
    }
    
    //******************************************************************************
    // Name: _AfterVisite
    // Desc: 后序遍历(非递归)
    //******************************************************************************
    void _AfterVisite(Node* tree)
    {
    	ResetTree(tree);
    
    	typedef vector<Node*> NodeStack;
    	NodeStack stack;
    	stack.push_back(tree);				// 初始化
    
    	while (stack.size())
    	{
    		Node* topNode = stack.back();
    		if (topNode->leftVisited && topNode->rightVisited)
    		{
    			cout<<topNode->data<<" ";
    		}
    
    		if (topNode->leftChild != NULL && !topNode->leftVisited)
    		{
    			stack.push_back(topNode->leftChild);
    			topNode->leftVisited = true;
    		}
    		else if (topNode->rightChild != NULL && !topNode->rightVisited)
    		{
    			stack.push_back(topNode->rightChild);
    			topNode->rightVisited = true;
    		}
    		else
    		{
    			// 针对叶子节点或者单边子节点的情况
    			if (topNode->leftChild == NULL || topNode->rightChild == NULL)
    			{
    				cout<<topNode->data<<" ";
    			}
    			stack.pop_back();
    		}
    	}
    }
    
    
    //******************************************************************************
    // Name: __AfterVisite
    // Desc: 非递归后根遍历思路二
    //******************************************************************************
    void __AfterVisite(Node* tree)
    {
    	typedef vector<Node*> StackNode;
    	StackNode stack;
    
    	Node *curNode;								// 当前结点 
    	Node *preNode = NULL;						// 前一次访问的结点 
    	stack.push_back(tree);
    
    	while(!stack.empty())
    	{
    		curNode = stack.back();
    
    		if((curNode->leftChild == NULL && curNode->rightChild == NULL) ||
    			(preNode != NULL && (preNode == curNode->leftChild || preNode == curNode->rightChild)))
    		{
    			cout<<curNode->data<<" ";			// 如果当前结点没有孩子结点或者孩子节点都已被访问过 
    			stack.pop_back();
    			preNode = curNode; 
    		}
    		else
    		{
    			if(curNode->rightChild != NULL)
    			{
    				stack.push_back(curNode->rightChild);	
    			}
    			if(curNode->leftChild != NULL)
    			{
    				stack.push_back(curNode->leftChild);
    			}
    		}
    	}    
    }
    
    //******************************************************************************
    // Name: LevelVisite
    // Desc: 层次遍历
    //******************************************************************************
    void LevelVisite(Node* tree)
    {
    	typedef list<Node*> QueueNode;
    	QueueNode queue;
    	queue.push_back(tree);
    
    	while (queue.size() > 0)			//由上至下,由左至右
    	{
    		Node* curNode = queue.front();
    		queue.pop_front();
    		cout<<curNode->data<<" ";
    
    		if (curNode->leftChild != NULL)
    		{
    			queue.push_back(curNode->leftChild);
    		}
    		if (curNode->rightChild != NULL)
    		{
    			queue.push_back(curNode->rightChild);
    		}
    	}
    }
    
    //******************************************************************************
    // Name: CaculateLeafNum
    // Desc: 统计叶子节点的数量
    //******************************************************************************
    int CaculateLeafNum(Node* tree)
    {
    	if (tree == NULL)
    	{
    		return 0;
    	}
    
    	if (tree->leftChild == NULL && tree->rightChild == NULL)	//孤立点
    	{
    		return 1;
    	}
    
    	//递归计算
    	int sum = 0;
    	sum += CaculateLeafNum(tree->leftChild);
    	sum += CaculateLeafNum(tree->rightChild);
    
    	return sum;
    }
    
    //******************************************************************************
    // Name: CaculateAllNodeNum
    // Desc: 统计所有节点数量
    //******************************************************************************
    int CaculateAllNodeNum(Node* tree)
    {
    	/*static int sum = 0;
    	if(tree != NULL)
    	{
    		sum += 1;
    
    		CaculateAllNodeNum(tree->leftChild);
    		CaculateAllNodeNum(tree->rightChild);
    	}*/
    
    	int sum = 0;
    	if (tree != NULL)
    	{
    		sum = 1;
    		sum += CaculateAllNodeNum(tree->leftChild);
    		sum += CaculateAllNodeNum(tree->rightChild);
    	}
    
    	return sum;	
    }
    
    //******************************************************************************
    // Name: CaculateDepth
    // Desc: 计算二叉树的深度
    //******************************************************************************
    int CaculateDepth(Node* tree)
    {
    	int leftDepth	= 0;
    	int rightDepth	= 0;
    
    	if(tree != NULL)
    	{
    		leftDepth = 1;
    		leftDepth += CaculateDepth(tree->leftChild);
    
    		rightDepth = 1;
    		rightDepth += CaculateDepth(tree->rightChild);
    	}
    
    	return leftDepth > rightDepth ? leftDepth : rightDepth;
    }
    
    //******************************************************************************
    // Name: CaculateWidth
    // Desc: 计算二叉树的宽度
    //******************************************************************************
    int CaculateWidth(Node* tree)
    {
    	if (tree == NULL)
    	{
    		return 0;
    	}
    
    	typedef list<Node*> QueueNode;
    	QueueNode queue;
    	unsigned int width = 0;
    	queue.push_back(tree);
    
    	while (queue.size() > 0)
    	{
    		unsigned int size = queue.size();
    
    		for (unsigned int i = 0; i < size; ++i)	// 上一层的节点全部出列,并压入下一层节点
    		{
    			Node* curNode = queue.front();
    			queue.pop_front();
    
    			if (curNode->leftChild != NULL)
    			{
    				queue.push_back(curNode->leftChild);
    			}
    
    			if (curNode->rightChild != NULL)
    			{
    				queue.push_back(curNode->rightChild);
    			}
    			
    		}
    		width = max(width, size);				// 与每一个size比较,取最大者
    	}
    
    	return width;
    }
    
    //******************************************************************************
    // Name: Release
    // Desc: 释放资源
    //******************************************************************************
    void Release(Node* tree)
    {
    	if(tree != NULL)
    	{
    		Release(tree->leftChild);
    		Release(tree->rightChild);
    		delete tree;
    		tree = NULL;
    	}
    }
    
    
    int main()
    
    {
    	// 数据输入
    	vector<int> dataVec;
    	int			tempValue;
    	cout<<"请输入二叉树的先序扩展序列(-1为空):"<<endl;
    	while(cin>>tempValue)
    	{
    		dataVec.push_back(tempValue);
    	}
    
    	// 二叉树的创建
    	Node* root = NULL;
    	root = CreateTree(root, dataVec);	
    
    	// 二叉显示
    	DisplayTree(root);
    
    	// 递归先根遍历
    	FirstVisite(root);
    	cout<<endl;
    
    	// 递归中根遍历
    	CenterVisite(root);
    	cout<<endl;
    
    	// 递归后根遍历
    	AfterVisite(root);
    	cout<<endl;
    
    	cout<<"----------------------------"<<endl;
    
    	// 非递归先根遍历
    	_FirstVisite(root);
    	cout<<endl;
    
    	// 非递归先根遍历二
    	__FirstVisite(root);
    	cout<<endl;
    
    	// 非递归中根遍历
    	_CenterVisite(root);
    	cout<<endl;
    
    	// 非递归中根遍历思路二
    	__CenterVisite(root);
    	cout<<endl;
    
    	// 非递归后根遍历
    	_AfterVisite(root);
    	cout<<endl;
    
    	// 非递归后根遍历思路二
    	__AfterVisite(root);
    	cout<<endl;
    
    	// 层次遍历
    	LevelVisite(root);
    	cout<<endl;
    
    	// 计算叶子节点数量
    	cout<<CaculateLeafNum(root)<<endl;
    
    	// 计算所有节点数量
    	cout<<CaculateAllNodeNum(root)<<endl;
    
    	// 计算二叉树深度
    	cout<<CaculateDepth(root)<<endl;
    
    	// 计算二叉树宽度
    	cout<<CaculateWidth(root)<<endl;
    
    	// 释放资源
    	Release(root);
    
    	system("pause");
    	return 0;
    }

    其他操作:

    Node* midLastToTree(const string& midIn, const string& lastIn)// 已知二叉树中序遍历和 
    {                                             //后序遍历序列,求二叉树的二叉链表结构
    	if (midIn.empty() || lastIn.empty())
    	{
    		return 0;
    	}
    
    	char rootC = *(lastIn.end() - 1); // 找出根结点
    	// 把字符串midIn分成两部分 
    	string::size_type rootIndex = midIn.find_first_of(rootC);
    	string leftMidIn = midIn.substr(0, rootIndex);
    	string rightMidIn = midIn.substr(rootIndex+1);
    	// 把字符串lastIn也分成两部分 
    	string leftLastIn;
    	string rightLastIn;
    	string::const_iterator curIter = lastIn.begin();
    	string::const_iterator endIter = lastIn.end();
    	for (; curIter!=endIter; ++curIter)
    	{
    		char c = *curIter;
    		if (leftMidIn.find_first_of(c)!=string::npos)
    		{
    			leftLastIn.push_back(c);
    		} else if (rightMidIn.find_first_of(c)!=string::npos)
    		{
    			rightLastIn.push_back(c);
    		}
    	}
    
    	Node* tree = new Node;
    	tree->c = rootC;
    	// 递归
    	tree->left = midLastToTree(leftMidIn, leftLastIn);
    	tree->right = midLastToTree(rightMidIn, rightLastIn);
    	return tree;
    }
    Node* firstMidToTree(const string& midIn, const string firstIn)// 已知二叉树中序遍历和
    {                                               //先序遍历序列,求二叉树的二叉链表结构
    	if (midIn.empty() || firstIn.empty())
    	{
    		return 0;
    	}
    
    	char rootC = *firstIn.begin();
    	// 把字符串midIn分成两部分
    	string::size_type rootIndex = midIn.find_first_of(rootC);
    	string leftMidIn = midIn.substr(0, rootIndex);
    	string rightMidIn = midIn.substr(rootIndex+1);
    	// 把字符串firstIn分成两部分
    	string leftFirstIn, rightFirstIn;
    	string::const_iterator curIter = firstIn.begin();
    	string::const_iterator endIter = firstIn.end();
    	while (curIter != endIter)
    	{
    		char c = *curIter++;
    		if (leftMidIn.find_first_of(c)!=string::npos)
    		{
    			leftFirstIn.push_back(c);
    		} else if (rightMidIn.find_first_of(c)!=string::npos)
    		{
    			rightFirstIn.push_back(c);
    		}
    	}
    
    	Node* tree = new Node;
    	tree->c = rootC;
    	// 递归
    	tree->left = firstMidToTree(leftMidIn, leftFirstIn);
    	tree->right = firstMidToTree(rightMidIn, rightFirstIn);
    	return tree;
    }


    非递归后根遍历思路三:

    void postOrder2(BinTree *root)    //非递归后序遍历
    {
        stack<BTNode*> s;
        BinTree *p=root;
        BTNode *temp;
        while(p!=NULL||!s.empty())
        {
            while(p!=NULL)              //沿左子树一直往下搜索,直至出现没有左子树的结点 
            {
                BTNode *btn=(BTNode *)malloc(sizeof(BTNode));
                btn->btnode=p;
                btn->isFirst=true;
                s.push(btn);
                p=p->lchild;
            }
            if(!s.empty())
            {
                temp=s.top();
                s.pop();
                if(temp->isFirst==true)     //表示是第一次出现在栈顶 
                 {
                    temp->isFirst=false;
                    s.push(temp);
                    p=temp->btnode->rchild;    
                }
                else                        //第二次出现在栈顶 
                 {
                    cout<<temp->btnode->data<<" ";
                    p=NULL;
                }
            }
        }    
    } 



  • 相关阅读:
    【阿里天池云-龙珠计划】薄书的机器学习笔记——快来一起挖掘幸福感!Task04
    薄书的pytorch项目实战lesson49-情感分类+蹭免费GPU
    薄书的博客园主题——awescnb
    # 详细分析MySQL事务日志(redo log和undo log)
    docker网络模式
    IOTOP
    磁盘分区知识
    # KVM虚拟化技术的内置快照和外置快照
    mysql MGR
    linux各种监控工具 (转)
  • 原文地址:https://www.cnblogs.com/javawebsoa/p/3231009.html
Copyright © 2011-2022 走看看