二叉树先序,中序,后序,层序遍历非递归

二叉树
//完全二叉树,满二叉树
//完全二叉树:有N层结点的二叉树,其中N-1层为满二叉树,且第N层的叶子结点从左向右,要么只有左叶子结点,不会存在只有右叶子节点没有左叶子节点的情况

//二叉树的存储有顺式存储即数组,也有链式存储即链表

//二叉树的基本操作即遍历

#include<iostream>
#include<stack>
#include<queue>
using namespace std;

typedef struct Node
{
	char *data;
	Node* lchild;
	Node* rchild;
	struct Node* next;
};


**先序遍历  VLR**
//判断根结点是否存在,若存在则入栈列,
//判断栈顶元素是否为空,若不为空则访问,出栈,
//栈顶元素的左右孩子不为空则入栈

void priorSearch(Node* head)
{
	stack<Node*>s;
	if (head == NULL)
		return;
	Node* cur = head;
	while (!s.empty()||cur) //当很结点和栈步同时为空说明遍历没有结束
	{
		while(cur)  //先序遍历遇到根结点则直接入栈
		{
			cout << cur->data;
			s.push(cur); 
			cur = cur->lchild;
		}
		Node* top = s.top(); //取栈顶元素说明根结点已经左子树已经访问过了
		s.pop();

		cur = top->rchild; //以子问题的方式访问右子树

	}
}

**中序遍历  LVR**
void middleSearch(Node* head)
{
	stack<Node*>s;
	Node* cur = head;
	while (!s.empty() || cur)  //当根结点和栈步同时为空说明没有遍历完成
	{
		while (cur)  //中序遍历遇到根节点直接入栈
		{ 
			s.push(cur);
			cur = cur->lchild;
		}
		Node* top = s.top(); //取栈顶元素,说明左子树和根节点已经访问过了
		cout << top->data;  //访问栈顶元素(即根结点)
		s.pop();
		top = top->rchild; //以子问题的方式访问右子树
	}
}

**后序遍历  LRV**
void laterSearch(Node* head)
{
	stack<Node*>s;  
	Node*cur = head;
	Node* pre = NULL;
	while (!s.empty() || cur)  //当根节点和栈不同时为空说明遍历没有结束
	{
		while (cur)//遇到根结点入栈
		{
			s.push(cur);
			cur = cur->lchild;
		}
		Node* top = s.top();  //栈顶元素不一点可以访问
		if (top->lchild == NULL || top->rchild == pre) //若栈顶元素左结点为空或右节点已经访问过才可以进行访问
		{
			cout << top->data; //访问栈顶元素 (即根结点) 
			top = pre;//更新前一个结点
			s.pop();
		}
		else
		{
			cur = cur->rchild;  //以子问题的方式访问右子树
		}
	}
}

**层序遍历  **
void levelSearch(Node* head)
{
	queue<Node*>q;
	if (head)
		q.push(head);  //根结点入队列
	while (!q.empty())
	{
		Node* front = q.front();
		cout << front->data;
		q.pop();
		if (front->lchild != NULL)
			q.push(front->lchild);
		if (front->rchild != NULL)
			q.push(front->rchild);		
	}
}

建造二叉树

//二叉树的构造

#include<iostream>
#include<cassert>
#include<queue>
#include<stack>

using namespace std;

template<class T>
struct TreeNode
{
	TreeNode(const T&val = T())
	:_val(val)
	, _lchild(0)
	, _rchild(0)
	{}
	T _val;    //节点值
	TreeNode<T>* _lchild;  //左孩子,右孩子
	TreeNode<T>* _rchild;
};


template<class T>
class BinaryTree
{
public:
	typedef Node<T> node;
	BinaryTree()   //无参构造函数
		:_root(NULL)
	{}

	BinaryTree(const T*a, size_t size, const T& val) //带参构造函数
	{
		assert(a);
		size_t index = 0;
		_root = CreatTree(a, size, val, index);
	}

	BinaryTree(const BinaryTree<T>& b) //拷贝构造
	{
		_root = Copy(b._root);
	}

	BinaryTree& operator=(const BinaryTree<T>& b) //赋值运算符重载
	{
		//if (this != &b)
		//{
		//	Node* tmp = Copy(b._root);
		//	Destroy(_root);
		//	_root = tmp;
		//}
		swap(b._root, _root);
		return *this;
	}


	~BinaryTree()   //析构函数
	{
		if (NULL != _root)
		{
			Destroy(_root);
			_root = NULL;
		}
	}

protected:  //按照先序遍历递归建树
	Node* CreateTree(const T* a, size_t size, const T&val, size_t &index)
	{
		assert(a);
		Node* root == NULL;
		if (a[index]!=val&&index<size)
		{
			root = new  Node(a[index]);
			root->lchild = CreateTree(a, size, val, ++index);
			root->rchild = CreateTree(a, size, val, ++index);
		}
		return root;
	}

	Node* Copy(Node* root)   //拷贝对象
	{
		Node* tmp = NULL;
		if (root)
		{
			tmp = new Node(root->val);
			tmp->lchild = Copy(root->_lchild);
			tmp->rchild = Copy(root->_rchild);
		}
		return tmp;
	}

	void Destroy(Node* &root)  //释放空间
	{
		if (root)   //用后序遍历方式释放空间
		{
			Destroy(root->_lchild);
			Destroy(root->_rchild);
			delete root;
			root = NULL;
		}
	}
private:
	Node* _root;  //根节点
};

常见二叉树问题

//求树的深度
size_t Depth(Node* root)
{
	if (root == NULL)
		return 0;
	else
		return Depth(root->lchild) > Depth(root->rchild) ?
		(Depth(root->lchild) + 1) : (Depth(root->rchild) + 1);
}

//求二叉树中节点个数
size_t Size(Node* root)
{
	size_t count = 0;
	if (root == NULL)
	{
		count = 0;
	}
	else
	{
		//节点个数=左子树节点+右子树节点+1
		count = Size(root->lchild) + Size(root->rchild) + 1;
	}
	return count;
}

//求二叉树中叶子节点的个数
size_t leafsize(Node* root)
{
	if (root == NULL)
		return 0;
	if (root->lchild == NULL&&root->rchild == NULL)
	{
		return 1;
	}
	else
	{
		return leafsize(root->lchild) + leafsize(root->rchild);
	}
}

//求二叉树第K层的节点个数

size_t Klevelsize(Node* root, size_t k)
{
	size_t count = 0;
	if (root == NULL)
		return 0;
	if (k == 1)
	{
		count++;
	}
	else
	{
		count = Klevelsize(root->lchild, k - 1) + Klevelsize(root->rchild, k - 1);
	}
	return count;

}


//判断一棵树是否为完全二叉树
bool IsComplete(Node* root)
{
	bool flag = true;
	queue<Node*>q;
	q.push(root);
	
	while (!q.empty())    //运用队列进行层序遍历
	{
		Node* front = q.front();
		q.pop();     //如果队首元素的左子树为空,则标志位假,如果层序遍历后面的节点还有子树说明不是完全二叉树
		if (front->lchild == NULL)  
			flag = false;
		else
		{
			if (flag == false)
			{
				return false;
			}
			q.push(front->lchild);
		}

		if (front->rchild == NULL)
			flag = false;
		else
		{
			if (flag == false)
				return false;
			q.push(front->rchild);
		}
	}
	return true;
}

//二叉树的镜像
void MirrorTree(Node* root)
{
	if (root == NULL)
		return;
	swap(root->lchild, root->rchild);
	MirrorTree(root->lchild);
	MirrorTree(root->rchild);
}
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值