第1关:头文件基本函数的实现
#pragma once
// # include <bits/stdc++.h>
#include <iostream>
#include <string>
#include <stack>
#include <queue>
using namespace std;
namespace exa
{
struct bnode
{
struct bnode *lchild, *rchild;
int ltag, rtag;
char data;
};
typedef bnode *bitre;
// 非递归读取拓展二叉树的先序遍历序列来构建原二叉树
static void load_bitre(bitre &t)
{
string s;
cin >> s;
int n = s.length();
if (n > 0)
{
stack<bitre> st;
t = (bitre)malloc(sizeof(bnode));
t->data = s[0];
t->lchild = t->rchild = NULL;
t->ltag = t->rtag = 0;
st.push(t);
for (int i = 1; i < n; i++)
{
if (s[i] == '.')
{
if (st.top()->lchild != NULL || s[i - 1] == '.')
st.pop();
continue;
}
bitre tmp = (bitre)malloc(sizeof(bnode));
tmp->data = s[i];
tmp->lchild = tmp->rchild = NULL;
tmp->ltag = tmp->rtag = 0;
if (st.top()->lchild == NULL && s[i - 1] != '.')
st.top()->lchild = tmp;
else
{
st.top()->rchild = tmp;
st.pop();
}
st.push(tmp);
}
}
}
// 递归读取拓展二叉树的先序遍历序列来构建原二叉树
/*
bitre loopload(bitre t, string str, int& pos)
{
if (str[pos] == '.')return NULL;
t = new bnode; t->data = str[pos];
t->ltag = t->rtag = 0;
t->lchild = loopload(t->lchild, str, ++pos);
t->rchild = loopload(t->rchild, str, ++pos);
return t;
}
static void load_bitre(bitre & t)
{
string str;
cin >> str;
int pos = 0;
t=loopload(t, str, pos);
}
*/
static void preorder(bitre t)
{
if (t == NULL)
return;
cout << t->data;
preorder(t->lchild);
preorder(t->rchild);
}
static void inorder(bitre t)
{
if (t == NULL)
return;
inorder(t->lchild);
cout << t->data;
inorder(t->rchild);
}
// 输出二叉树的先序遍历序列和中序遍历序列;
// 格式:
// PreOrder: xxxxxxx
// InOrder: xxxxxxx
static void display_bitre(bitre &root)
{
cout << "PreOrder: ";
preorder(root);
cout << "\nInOrder: ";
inorder(root);
cout << endl;
}
// 显示线索二叉树
// 每一行的格式为 data(i) ltag(i) lchild(i) rtag(i) rchild(i)
// 无孩子结点则 child(i) 为 '.'
static void display_thread_bitre(bitre &t)
{
if (t == NULL)
return;
cout << t->data << " " << t->ltag << " ";
if (t->ltag == 1 && t->lchild == NULL)
cout << ". ";
else
cout << t->lchild->data << " ";
cout << t->rtag << " ";
if (t->rtag == 1 && t->rchild == NULL)
cout << "." << endl;
else
cout << t->rchild->data << endl;
if (t->ltag == 0)
display_thread_bitre(t->lchild);
if (t->rtag == 0)
display_thread_bitre(t->rchild);
}
static void display_thbitre(bitre &t)
{
display_thread_bitre(t);
}
// 先序线索化二叉树
static void order_thread_bitre(bitre &t, bitre &pre)
{
if (t == NULL)
return;
if (t->lchild == NULL)
{ // 前驱
t->ltag = 1;
t->lchild = pre;
}
if (t->rchild == NULL)
t->rtag = 1; // 为当前节点后继做铺垫
if (pre != NULL && pre->rtag == 1)
pre->rchild = t; // 前一个节点后继
pre = t;
if (t->ltag == 0)
order_thread_bitre(t->lchild, pre);
if (t->rtag == 0)
order_thread_bitre(t->rchild, pre);
}
// 中序线索化二叉树
static void in_thread_bitre(bitre &t, bitre &pre)
{
if (t == NULL)
return;
in_thread_bitre(t->lchild, pre);
if (t->lchild == NULL)
{ // 前驱
t->ltag = 1;
t->lchild = pre;
}
if (t->rchild == NULL)
t->rtag = 1; // 为当前节点后继做铺垫
if (pre != NULL && pre->rtag == 1)
pre->rchild = t; // 前一个节点后继
pre = t;
in_thread_bitre(t->rchild, pre);
}
}
第2关:求线索二叉树的叶子节点数
#include "test.h"
#include "../btrechar.h" // 引用库函数文件
namespace exa { //请在命名空间内编写代码,否则后果自负
int bitreleaf(bitre t)
{
if (t == NULL)
return 0;
else if (t->ltag == 1 && t->rtag == 1) // Blank 1
return 1;
else if (t->ltag == 1) // Blank 2
return (bitreleaf(t->rchild));
else if (t->rtag == 1) // Blank 3
return (bitreleaf(t->lchild));
else
return bitreleaf(t->lchild) + bitreleaf(t->rchild);
}
void solve()
{
bitre t, tin;
tin=nullptr;
load_bitre(t); // 读二叉树
in_thread_bitre(t, tin); // 中序线索化
// display_thread_bitre(t); // 显示线索二叉树
display_thread_bitre(t);
printf("%d", bitreleaf(t)); // 调用算法求解
}
}
第3关:在线索二叉树上插入中序后继结点
#include "test.h"
#include "../btrechar.h" // 引用库函数文件
namespace exa { //请在命名空间内编写代码,否则后果自负
void insert_node_to_Lchild(bitre &P, bitre &Q)
{
P->lchild = Q->lchild;
P->ltag = 1;//Blank 4
P->rchild = Q;
P->rtag = 1;//Blank 5
Q->lchild = P;
Q->ltag = 0;//Blank 6
}
void insert_node_to_Rchild(bitre &P, bitre &Q)
{
P->rchild = Q->rchild;
P->rtag = 1;
P->lchild = Q;//Blank 7
P->ltag = 1;//Blank 8
Q->rchild = P;//Blank 9
Q->rtag = 0;//Blank 10
}
void insert_root_next(bitre &T, char x)
{
bitre P, Q;
P=(bitre)malloc(sizeof(struct bnode));
P->data = x;
if (T->rtag == 1) insert_node_to_Rchild(P, T);
else{
Q = T->rchild;
while (Q->ltag == 0)//Blank 9 搜索中序后继
Q = Q->lchild;
insert_node_to_Lchild(P, Q);
}
display_thread_bitre(T);
}
void solve()
{
bitre t, tin = NULL;
load_bitre(t);
display_bitre(t);
in_thread_bitre(t, tin); //中序线索化二叉树
display_thread_bitre(t); //显示线索二叉树
insert_root_next(t, 'x'); //调用算法运行以检验
}
}
第4关:先序遍历先序线索二叉树
#include "test.h"
#include "../btrechar.h" // 引用库函数文件
namespace exa { //请在命名空间内编写代码,否则后果自负
string solve(bitre t)
{
string ans;
while (t != NULL) {
ans += t->data;
if (t->ltag == 0) t = t->lchild;
else if (t->rtag == 0) t = t->rchild;
else t = t->rchild;
}
return ans;
}
}
第5关:中序遍历中序线索二叉树
#include "test.h"
#include "../btrechar.h" // 引用库函数文件
namespace exa { //请在命名空间内编写代码,否则后果自负
string solve(bitre t)
{
string ans;
while (t != NULL) {
ans += t->data;
if (t->rtag == 1) t = t->rchild;
else {
t = t->rchild;
while (t->ltag == 0) t = t->lchild;
}
}
return ans;
}
}
第6关:在先序线索二叉树中插入节点
#include "test.h"
#include "../btrechar.h" // 引用库函数文件
namespace exa { //请在命名空间内编写代码,否则后果自负
void solve(bitre t)
{
if(!t->ltag){
t = t->lchild;
while(true){
if(!t->rtag){
t = t->rchild;
}else if(!t->ltag){
t = t->lchild;
}else{
break;
}
}
bitre newnode = (bitre)malloc(sizeof(bnode));
newnode->data = 'x';
newnode->rtag = 1;
newnode->rchild = t->rchild;
newnode->lchild = t;
newnode->ltag = 1;
t->rchild = newnode;
t->rtag = 0;
}else{
bitre newnode = (bitre)malloc(sizeof(bnode));
newnode->data = 'x';
newnode->lchild = t;
newnode->ltag = 1;
newnode->rchild = t->rchild;
newnode->rtag = 1;
t->ltag = 0;
t->lchild = newnode;
}
}
}
第7关:中序次序线索化二叉树
#include "test.h"
#include "../btrechar.h" // 引用库函数文件
namespace exa { //请在命名空间内编写代码,否则后果自负
void last_thread_bitre_(bitre & t, bitre & pre) {
if (t!=NULL) {
if (t->ltag == 0)
last_thread_bitre_(t->lchild, pre);
if (t->rtag == 0)
last_thread_bitre_(t->rchild, pre);
if ((pre != NULL) && (pre->rtag == 1))
pre->rchild = t;
if (t->lchild == NULL) {
t->lchild = pre;
t->ltag = 1;
}
else t->ltag = 0;
if (t->rchild == NULL)
t->rtag = 1;
else t->rtag = 0;
pre = t;
}
}
void solve(bitre &t)
{
bitre tin = NULL;
last_thread_bitre_(t, tin);
}
}
第8关:后序次序线索化二叉树
#include "test.h"
#include "../btrechar.h" // 引用库函数文件
namespace exa { //请在命名空间内编写代码,否则后果自负
void last_thread_bitre_(bitre & t, bitre & pre) {
if (t!=NULL) {
if (t->ltag == 0)
last_thread_bitre_(t->lchild, pre);
if (t->rtag == 0)
last_thread_bitre_(t->rchild, pre);
if ((pre != NULL) && (pre->rtag == 1))
pre->rchild = t;
if (t->lchild == NULL) {
t->lchild = pre;
t->ltag = 1;
}
else t->ltag = 0;
if (t->rchild == NULL)
t->rtag = 1;
else t->rtag = 0;
pre = t;
}
}
void solve(bitre &t)
{
bitre tin = NULL;
last_thread_bitre_(t, tin);
}
}