数据结构:线索二叉树的遍历

题目:

中序线索化上述二叉树并找出根结点的前驱和后继。

思路:

(1)利用递归函数创建一颗普通的二叉树
(2)1.左子树线索化(返回修改后的pre);
2.当前结点p线索化
建前驱线索(当前结点左空,指向pre);
建后继线索(pre右空,pre指向当前结点);
重新修改前驱结点p指针为 pre;
3.右子树线索化(将新的pre输入)
(4)将pre的右标志数置1,右子树置NULL。
(5)将该线索树进行中序遍历,并将结果依次放入vector中
(6)在vector中查找相对应的结点值,前后值则分别为前驱和后置,同时对可能的错误和特殊情况进行处理。

代码块:

#include "pch.h"
#include <iostream>
#include<vector>
using namespace std;
vector<char> tmp;
struct Btree {//二叉树结构
	char data;
	Btree*lchild;
	Btree*rchild;
	int ltag;
	int rtag;
};
void create(Btree *&t)//创建二叉树
{
	char data;
	cin >> data;
	t = new Btree;
	if (data == '#') t = NULL;//以#为终止符号
	else {//标志数均为0,左右孩子为NULL,递归建立树
		t->data = data;
		t->ltag = 0;
		t->rtag = 0;
		t->lchild = NULL;
		t->rchild = NULL;
		cout << "请输入" << data << "的左子树:"; create(t->lchild);
		cout << "请输入" << data << "的右子树:";	create(t->rchild);
	}
}
void InThreading(Btree*&t, Btree*&pre)//中序线索化二叉树
{
	if (t) {
		InThreading(t->lchild, pre);//线索化左子树
		if (t->lchild == NULL) {//如果结点左孩子为NULL
			t->lchild = pre;//将其左孩子置为前驱
			t->ltag = 1;//标志数为1
		}
		if (pre != NULL && pre->rchild == NULL) {//如果前驱的右孩子为NULL
			pre->rchild = t;//将其右孩子置为当前结点
			pre->rtag = 1;//右标志数为1
		}
		pre = t;//前驱结点置为当前结点
		InThreading(t->rchild, pre);//线索化右子树
	}
}
void CreatThreading(Btree *&tree)//创建线索化二叉树
{
	Btree*pre = NULL;
	if (tree == NULL) cout << "该树为空树!\n";//空树处理
	if (tree != NULL) {
		InThreading(tree, pre);//线索化二叉树
		pre->rchild = NULL;//将最后一个结点右孩子置为NULL
		pre->rtag = 1;//最后一个结点右标志数置1
	}
}
void ldr(Btree *&tree)//中序遍历线索化二叉树
{
	Btree*p = tree;
	while (p)
	{
		while (p->ltag == 0) p = p->lchild;//具有左孩子一直往下搜索
		cout << p->data<<'\t';
		tmp.push_back(p->data);
		while (p->rtag==1&&p->rchild)//若无右孩子,则往后继寻找
		{
			p = p->rchild;
			cout << p->data<<'\t';
			tmp.push_back(p->data);
		}
		p = p->rchild;//结点转为右孩子
	}
}
int search(Btree *tree, vector<char>tmp)//查找结点位置
{
	cout << "请输入要查找的根结点:";
	char res;
	cin >> res;
	int i;
	for (i = 0; i < tmp.size(); i++)
	{
		if (res == tmp[i]) break;
	}
	return i;
}
int main()
{
	Btree*tree = new Btree;
	cout << "请输入首根结点:";
	create(tree);
	CreatThreading(tree);
	cout << "中序遍历线索化二叉树结果:\n";
	ldr(tree);
	cout << endl;
	while (true)
	{
		int pos = search(tree, tmp);
		if (pos == 0)
		{
			cout << "无前驱结点"<<endl;
			cout << "后继结点为:" << tmp[1]<<endl;
		}
		else if (pos == tmp.size() - 1)
		{
			cout << "前驱结点为" << tmp[pos - 1] << endl;
			cout << "无后继结点" << endl;
		}
		else if (pos >= tmp.size()) cout << "查无此结点,请检查!"<<endl;
		else {
			cout << "前驱结点为" << tmp[pos - 1] << endl;
			cout << "后继结点为" << tmp[pos + 1] << endl;
		}
	}
}

效果图:

图一为所构建的二叉树,图二为程序构建二叉树的过程,图三为查找根结点可能出现的情况及处理。
(1)根结点无前驱结点,有后继结点
(2)根结点有前驱结点,无后继结点
(3)根结点有前驱结点,有后继结点
(4)无此结点

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

发布了330 篇原创文章 · 获赞 13 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/weixin_43981315/article/details/103914987