T m这道题卡了我好几天 真 T m心情非常烦躁哈 看CSDN上 那些人写的代码 写的不清不楚 你tama能不能写详细点啊 伪代码真的很恶心好吧?
感谢中序线索化二叉树及遍历 - 百度文库
带来的部分代码 好不容易看见的好代码
还有那个严蔚敏的书 写的是什么乱七八糟的东西 细节也不交代清楚 看的我真的恶心死了 cao
tama最后还不是得自己来写 真tm zhizhang 连教学用书都写不好 详细点会死吗?Gross!你写不好我看nm的书呢?
首先给大家讲一下 我写代码关于空指针和野指针的问题
#include
using namespace std;
struct student
{
student *p;
student *q;
}
int main()
{
student* m;
if(m)
{
cout<<"1";
}
else if(m==NULL)
{
cout<<"2";
}
student *i=new student
if(i)
{
cout<<"3";
}
else if(i==NULL)
{
cout<<"4";
}
return 0;
}
大家先要明白这个野指针初始化的问题。上述代码 m如果没有new student的话 会报错所以输出不了
而 i 进行了new student 所以可以 但只能输出3 i指针默认不是NULL所以不会输出4
最后结果 这段代码 只会输出 :3
然后我要讲一下线索化二叉树的思路
线索化二叉树的步骤是什么,像现在给大家归纳一下。(耐心看完)
总结:
建立普通二叉树--->带头结点线索化或者直接无头结点线索化----->中序遍历线索二叉树---->结果一
建立普通二叉树-->中序遍历普通二叉树--->结果二
结果一和结果二一模一样。
这次我采用的是不带头节点的建立线索二叉树。
函数板块主要有 建立树 线索化 遍历输出
你所谓的全局变量初始化 你能不能写完写详细一点 ?
你如果直接在全局区域写一个 student*pre;后面运行的时候是会报错的!!!!!!!!!
有很多博客 就直接给你在全局区域这样写 student*pre错错错错!!!
你要实体化student *pre=new student(对对对!)才行,这tama才叫初始化! 写得不清不楚的真的口区。
还有我画五角星那一段 很明显就有问题 !pre->rchild
如果pre刚开始是空指针要怎么办?直接就报错了!
正确的 代码我放在下面 大家自己对比一下
void clue_tree(student *p)
{
if (p)
{
clue_tree(p->left);
if (p->left==NULL)//左孩子为空链接前驱
{
p->left = pre;
p->tagleft = 1;
}
if (pre!=NULL&&pre->right==NULL)//pre右孩子为空链接后驱
{
pre->right = p;
pre->tagright = 1;
}
pre = p;
if (p->tagright == 0 && p->right == NULL)
{
p->tagright = 1;
}
clue_tree(p->right);
}
}
然后再和大家强调一下,书上这个中序遍历 是带头节点的中序遍历 一定看清楚。
我接下来写的是不带头节点的遍历
如果你线索化的时候用的是不带头结点的线索化 那书上这个遍历方式就会报错
接下来我们用例题来实验一下
23 线索二叉树:中序线索二叉树的遍历
作者: 冯向阳时间限制: 1S章节: DS:树
截止日期: 2022-06-30 23:55:00
问题描述 :
目的:使用C++模板设计中序线索二叉树的抽象数据类型(ADT)。并在此基础上,使用中序线索二叉树ADT的基本操作,设计并实现简单应用的算法设计。
内容:(1)请参照二叉树的ADT模板,设计中序线索二叉树的抽象数据类型。(由于该环境目前仅支持单文件的编译,故将所有内容都集中在一个源文件内。在实际的设计中,推荐将抽象类及对应的派生类分别放在单独的头文件中。参考教材、课件,以及网盘中的链表ADT原型文件,自行设计二叉树的ADT。)
(2)ADT的简单应用:使用该ADT设计并实现若干遍历线索二叉树的算法设计。
应用:要求设计一个算法,对建立的中序线索二叉树进行遍历。
提示:中序遍历线索二叉树,首先找到第一个访问的结点,即最左下结点,然后通过查找后继结点的方法进行遍历。
参考函数原型:
中序线索二叉树的遍历(共有成员函数)
//中序线索二叉树的遍历
template
void Thread_BinaryTree
输入说明 :
第一行:表示无孩子或指针为空的特殊分隔符
第二行:二叉树的先序序列(结点元素之间以空格分隔)
输出说明 :
第一行:中序线索二叉树的遍历结果
输入范例 :
#
A B # C D # # E # # F # G # H # #
输出范例 :
B(1,0),D(1,1),C(0,0),E(1,1),A(0,0),F(1,0),G(1,0),H(1,1)
student* find_next(student* & p)
void clue_tree(student *p)
两个难点函数 好好理解
注意看清楚 全局变量pre是怎么初始化的!!!
#include
#include
using namespace std;
int m = 1;
struct student
{
string data;
student* left;
student* right;
int tagleft=0;
int tagright=0;
};
//先序建立二叉树
void creat(student*& T, string kk)
{
string ch;
cin >> ch;
if (ch == kk)
{
T = NULL;
}//但凡输入了#号 该节点下一位停止
else
{
T = new student;
T->data = ch;
creat(T->left, kk);
creat(T->right, kk);
}
}
//二叉树的线索化 重点函数0号
student* pre = new student;//这才是正确的初始化 严老师你看清楚
void clue_tree(student *p)
{
if (p)
{
clue_tree(p->left);
if (p->left==NULL)//左孩子为空链接前驱
{
p->left = pre;
p->tagleft = 1;
}
if (pre!=NULL&&pre->right==NULL)//pre右孩子为空链接后驱
{
pre->right = p;
pre->tagright = 1;
}
pre = p;
if (p->tagright == 0 && p->right == NULL)
{
p->tagright = 1;
}//这段是我自己加的 用来保证最后一个元素的tagright为1 否则它会默认是0 不满足该题 要求
//比如ABCD A的tagleft=1 虽然左边没有元素 但是仍有线索 线索指向NULL
//同理 D后面虽然已经没有元素了 但仍有线索 线索指向NULL 如果没有这段代码 d的tagright默认=0;
clue_tree(p->right);
}
}
//重点函数1 找到后面一个应该输出元素 列如输出顺序是 ABCDEF 不管这个二叉树什么样子 B后面就是C C后面就是D
student* find_next(student* & p)
{
student* next=NULL;
student* q;
if (p->tagright == 1)
{
next = p->right;//直接利用我们的线索 因为tag=1的时候 right就直接链接我们的后驱
}
else if (p->tagright == 0)//没有线索
{
if (p->right == NULL)
{
next = NULL;
}
else if (p->right != NULL)//
{
q = p->right;
while (q->tagleft == 0)
{
q = q->left;
}
next = q;
}
}
return next;//如果这里的p指的是是C的话 这里返回的next 指的就是D
}
//重点函数2找到 中序遍历应该输出的头一个元素
student* find_the_first_student(student *& root)
{
student* q = root;
if (q)
{
while (q->left!=NULL)
{
q = q->left;
}
}
return q;
}
//重点函数3 函数1 2仅在其中被利用
void display_the_tree(student *&root)
{
student* p;
p = find_the_first_student(root);
while (p != NULL)
{
//
if (m == 0)
{
cout << ",";
}
m = 0;
cout << p->data;
cout << "(";
cout << p->tagleft;
cout << ",";
cout << p->tagright;
cout << ")";
//上述代码用来输出 m用来控制逗号
p = find_next(p);
}
}
int main()
{
pre = NULL;//这tm才叫初始化 书上写些锤 子
student* root;
string kk;
cin >> kk;
creat(root, kk);//
//接下来是不带头节点的线索化
clue_tree(root);//正确
//接下来两步骤是遍历同时输出
display_the_tree(root);
return 0;
}