非递归建立二叉树

非递归建立二叉树

前提

通过二叉链表建立二叉树,二叉链表的节点结构如下:

template<class T>
struct BiNode {
	T data;											//节点数据
	BiNode<T>* lchild;								//左孩子
	BiNode<T>* rchild;								//右孩子
};

二叉树类的结构如下:

template<class T>
class BiTree {
private:
	BiNode<T>* root;								//根节点
public:
	BiTree(T data[], int n);						//构造函数
	void PreOrder();								//前序遍历
	void InOrder();									//中序遍历
	void PostOrder();								//后序遍历
	void LevelOrder();								//层序遍历
	~BiTree();										//析构函数
	int GetDepth();									//获取二叉树的深度
	void GetPath(T node);							//获取指定节点的路径
	void GetPath(BiNode<T>* node);					//获取指定节点指针的路径
	BiNode<T>* GetNode(T node);						//获取指定元素的节点指针
};

基本思想

二叉树建立的过程如下图所示:
非递归建立
可以利用栈来实现非递归建立,另外还需要创建一种栈节点结构,该结构包括:

  • 一个BiNode<T>类型的指针p,用于存放指向该二叉树节点的指针;
  • 一个int类型变量i,用于存放该二叉树节点在顺序存储结构中的位置;
  • 一个int类型变量stage,用于表示该二叉树节点的创建状态。该节点的创建状态有4种:
    • stage = 0时,表示pNULL,需要为p创建空间,并将data中的相应数据存入p->data
    • stage = 1时,表示还未创建p->lchildp->rchild,需要为p->lchild创建空间,并将data中的相应数据存入左孩子中;
    • stage = 2时,表示已创建p->lchild,还未创建p->rchild,需要为p->rchild创建空间,并将data中相应数据存入右孩子中;
    • stage = 3时,表示p->lchildp->rchild均已创建,则该节点可以出栈。

注意stage只表示p的创建情况,与p的左孩子和右孩子最后是否为NULL没有关系。)

C++描述如下:

template<class T>
struct Node {
	BiNode<T>* p;
	int i;											//对应初始化数组中的位置
	//访问该节点时的状态。
	//0表示需创建该节点,1表示需创建该节点的左孩子,2表示需创建该节点的右孩子,3表示需将该节点出栈
	int stage;
};

建立起的二叉树还需要将root指向根节点,以便通过root查找该二叉树。通过观察上图中二叉树的建立过程,可以发现,每当栈中只有一个节点时,该节点即为根节点,那么可以在循环的过程中加入判断栈长的语句,进而将root指向根节点。而且,根节点总是最后一个出栈,不必担心在循环中二叉树发生变化而root没有变化。

非递归建立二叉树的具体步骤如下:

  • [1]将root置空,存入Node中,并设定stage为0,然后入栈;
  • [2]判断栈是否为空,若为空,结束;若不为空,执行[3];
  • [3]取栈顶元素top;
    • [3.1]判断栈中元素个数是否为1,若为1,root=top->p;否则,执行下一步;
    • [3.2]判断top->stage的数值:
      • [3.2.1]stage=0:初始化top->p,然后将data中第top->i个元素存入top->p中,更改top->stage为1;
      • [3.2.2]stage=1:初始化top->p的左孩子,然后将data中第top->i*2个元素存入top->p的左孩子中,其次将该左孩子入栈,其stage设为0,最后更改top->stage为2;
      • [3.2.3]stage=2:初始化top->p的右孩子,然后将data中第top->i*2+1个元素存入top->p的右孩子中,其次将该右孩子入栈,其stage设为0,最后更改top->stage为3;
      • [3.2.4]stage>2:top出栈;
  • [4]返回[2]。

C++描述

构造函数:BiTree(T data[], int n);参数:data数组是二叉树的顺序存储结构,n表示数组的长度;

template<class T>
BiTree<T>::BiTree(T data[], int n) {
	root = NULL;									//初始化根节点
	stack<Node<T>*>st;								//栈
	Node<T>* no = new Node<T>;
	no->p = root;									//将根节点存入Node节点中
	no->i = 1;
	no->stage = 0;
	st.push(no);									//入栈
	while (!st.empty()) {
		no = st.top();								//取栈顶元素
		if (st.size() == 1) {
			root = no->p;							//当栈中只剩一个元素时取该元素中存放的节点为根节点
		}
		if (no->stage == 0) {						//stage为0时,创建该节点
			BiNode<T>* r = new BiNode<T>;
			r->data = data[no->i - 1];
			r->lchild = r->rchild = NULL;
			no->p = r;
			no->stage = 1;							//更改stage
		}
		else if (no->stage == 1) {					//stage为1时,创建左孩子
			BiNode<T>* r;
			int i = no->i * 2;
			if ((i <= n) && (data[i - 1] != NULL)) {
				r = new BiNode<T>;
				r->data = data[i - 1];
				r->lchild = r->rchild = NULL;
			}
			else {
				r = NULL;
			}
			no->p->lchild = r;
			no->stage = 2;							//更改stage
			if (r != NULL) {
				no = new Node<T>;
				no->p = r;
				no->i = i;
				no->stage = 1;
				st.push(no);						//左孩子节点入栈
			}
		}
		else if (no->stage == 2) {					//stage为2时,创建右孩子
			BiNode<T>* r;
			int i = no->i * 2 + 1;
			if ((i <= n) && (data[i - 1] != NULL)) {
				r = new BiNode<T>;
				r->data = data[i - 1];
				r->lchild = r->rchild = NULL;
			}
			else {
				r = NULL;
			}
			no->p->rchild = r;
			no->stage = 3;							//更改stage
			if (r != NULL) {
				no = new Node<T>;
				no->p = r;
				no->i = i;
				no->stage = 1;
				st.push(no);						//右孩子节点入栈
			}
		}
		else {										//stage为其余情况时,栈顶元素出栈
			st.pop();
		}
	}
}

这里放上我的完整代码:非递归建立二叉树及测试代码

  • 2
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值