提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
文章目录
A. DS二叉树–基于数组存储的构建
题目描述
任意二叉树可以根据完全二叉树性质保存在一个数组中。已知二叉树的数组存储,用程序构建该二叉树。
提示:用递归方法或非递归都可以
递归方法的代码框架如下:
输入
第一行输入一个整数t,表示有t个测试数据
第二行起输入二叉树的数组存储结果,空树用字符‘0’表示,输入t行
数组的数据由大写字母和0表示
输出
逐行输出每个二叉树的先序结果
输入样例1
3
ABC0D
ABCDEF000G
ABEC0F0D0
输出样例1
ABDC
ABDEGCF
ABCDEF
代码
#include<iostream>
#include <string>
using namespace std;
class BiTreeNode{
public:
char data;
BiTreeNode *LeftChild;
BiTreeNode *RightChild;
BiTreeNode():LeftChild(NULL),RightChild(NULL){}
~BiTreeNode(){}
};
class BiTree{
private:
BiTreeNode *Root;
int pos;
string strTree;
BiTreeNode* CreateBiTree(int pos);
void PreOrder(BiTreeNode *t);
public:
BiTree(){}
~BiTree(){}
void CreateTree (string TreeArray);
void PreOrder();
};
void BiTree::CreateTree(string TreeArray) {
pos=0;
strTree.assign(TreeArray);
Root=CreateBiTree(0);
}
BiTreeNode* BiTree::CreateBiTree(int pos) {
BiTreeNode *T;
char ch;
if(pos>=strTree.size()) return NULL;
ch=strTree[pos];
if(ch=='0')
T=NULL;
else{
T=new BiTreeNode();
T->data=ch;
T->LeftChild=CreateBiTree(pos*2+1);
T->RightChild=CreateBiTree(pos*2+2);
}
return T;
}
void BiTree::PreOrder() {
PreOrder(Root);
}
void BiTree::PreOrder(BiTreeNode *t) {
if(t!=NULL){
cout<<t->data;
PreOrder(t->LeftChild);
PreOrder(t->RightChild);
}
}
int main(void){
int t,i;
string str;
cin>>t;
while(t--){
BiTree p;
cin>>str;
p.CreateTree(str);
p.PreOrder();
cout<<endl;
}
return 0;
}
B. DS二叉树–层次遍历
题目描述
层次遍历二叉树,是从根结点开始遍历,按层次次序“自上而下,从左至右”访问树中的各结点。
建树方法采用“先序遍历+空树用0表示”的方法
要求:采用队列对象实现,函数框架如下:
输入
第一行输入一个整数t,表示有t个测试数据
第二行起输入二叉树先序遍历的结果,空树用字符‘0’表示,输入t行
输出
逐行输出每个二叉树的层次遍历结果
输入样例1
2
AB0C00D00
ABCD00E000FG00H0I00
输出样例1
ABDC
ABFCGHDEI
代码
#include<bits/stdc++.h>
using namespace std;
class BiTreeNode {
public:
char data;
BiTreeNode* LeftChild;
BiTreeNode* RightChild;
BiTreeNode():LeftChild(NULL),RightChild(NULL){}
~BiTreeNode(){}
};
class BiTree {
private:
BiTreeNode* Root;
int pos;
string strTree;
BiTreeNode* CreateBiTree();
void LevelOrder(BiTreeNode *t);
public:
BiTree() {}
~BiTree() {}
void CreateTree(string TreeArray);
void LevelOrder();
};
void BiTree::CreateTree(string TreeArray) {
pos = 0;
strTree.assign(TreeArray);
Root = CreateBiTree();
}
BiTreeNode* BiTree::CreateBiTree() {
BiTreeNode* T;
char ch;
ch = strTree[pos++];
if (ch == '0')
T = NULL;
else {
T = new BiTreeNode();
T->data = ch;
T->LeftChild = CreateBiTree();
T->RightChild = CreateBiTree();
}
return T;
}
void BiTree::LevelOrder() {
LevelOrder(Root);
}
void BiTree::LevelOrder(BiTreeNode *t) {
queue<BiTreeNode*> tq;
BiTreeNode*p=t;
if(p) tq.push(p);
while(!tq.empty()){
p=tq.front();
tq.pop();
cout<<p->data;
if(p->LeftChild) tq.push(p->LeftChild);
if(p->RightChild) tq.push(p->RightChild);
}
}
int main()
{
int t;
string s;
cin >> t;
for (int i = 0; i < t; i++) {
cin >> s;
BiTree T;
T.CreateTree(s);
T.LevelOrder();
cout << endl;
}
}
C. DS二叉树–左叶子数量
题目描述
计算一颗二叉树包含的叶子结点数量。
左叶子是指它的左右孩子为空,而且它是父亲的左孩子
提示:可以用三叉链表法,也可以用现有算法对两层结点进行判断
建树方法采用“先序遍历+空树用0表示”的方法
输入
第一行输入一个整数t,表示有t个测试数据
第二行起输入二叉树先序遍历的结果,空树用字符‘0’表示,输入t行
输出
逐行输出每个二叉树的包含的左叶子数量
输入样例1
3
AB0C00D00
AB00C00
ABCD0000EF000
输出样例1
0
1
2
代码
#include<iostream>
#include <string>
using namespace std;
class BiTreeNode {
public:
char data;
BiTreeNode *LeftChild;
BiTreeNode *RightChild;
BiTreeNode():LeftChild(NULL),RightChild(NULL) {}
~BiTreeNode() {}
};
class BiTree {
private:
BiTreeNode *Root;
int pos;
string strTree;
BiTreeNode* CreateBiTree();
void lel(BiTreeNode *fa,BiTreeNode *s);
public:
int cnt=0;
BiTree() {}
~BiTree() {}
void CreateTree (string TreeArray);
void lel();
};
void BiTree::CreateTree(string TreeArray) {
pos=0;
strTree.assign(TreeArray);
Root=CreateBiTree();
}
BiTreeNode* BiTree::CreateBiTree() {
BiTreeNode *T;
char ch;
ch=strTree[pos++];
if(ch=='0')
T=NULL;
else {
T=new BiTreeNode();
T->data=ch;
T->LeftChild=CreateBiTree();
T->RightChild=CreateBiTree();
}
return T;
}
void BiTree::lel() {
lel(Root,Root);
}
void BiTree::lel(BiTreeNode *fa,BiTreeNode *s) {
if(s!=NULL) {
if(s->LeftChild==NULL&&s->RightChild==NULL&&s==fa->LeftChild)
cnt++;
lel(s,s->LeftChild);
lel(s,s->RightChild);
}
}
int main(void) {
int t,i;
string str;
cin>>t;
while(t--) {
BiTree p;
cin>>str;
p.CreateTree(str);
p.lel();
cout<<p.cnt<<endl;
}
return 0;
}
D. DS二叉树—二叉树镜面反转
题目描述
假设二叉树用二叉链表存储,用先序序列结果创建。输入二叉树的先序序列,请你先创建二叉树,并对树做个镜面反转,再输出反转后的二叉树的先序遍历、中序遍历、后序遍历和层序遍历的序列。所谓镜面反转,是指将所有非叶结点的左右孩子对换。
–程序要求–
若使用C++只能include一个头文件iostream;若使用C语言只能include一个头文件stdio
程序中若include多过一个头文件,不看代码,作0分处理
不允许使用第三方对象或函数实现本题的要求
输入
测试次数t
每组测试数据是一个二叉树的先序遍历序列,#表示空树
输出
对每棵二叉树,输出镜面反转后的先序、中序、后序和层次遍历序列。如果空树,输出四个NULL(后面不加空格)。如下:
NULL
NULL
NULL
NULL
输入样例1
3
41#32###65##7##
AB#C##D##
AB##C##
输出样例1
4 6 7 5 1 3 2
7 6 5 4 3 2 1
7 5 6 2 3 1 4
4 6 1 7 5 3 2
A D B C
D A C B
D C B A
A D B C
A C B
C A B
C B A
A C B
代码
#include <iostream>
using namespace std;
class BiTreeNode {
public:
char data;
BiTreeNode *LeftChild;
BiTreeNode *RightChild;
BiTreeNode():LeftChild(NULL),RightChild(NULL) {}
~BiTreeNode() {}
};
class BiTree {
private:
BiTreeNode *Root;
int pos;
string strTree;
BiTreeNode* CreateBiTree();
void PreOrder(BiTreeNode *t);
void InOrder(BiTreeNode *t);
void PostOrder(BiTreeNode *t);
void reve(BiTreeNode *t);
void LevelOrder(BiTreeNode *t);
public:
BiTree() {}
~BiTree() {}
void CreateTree (string TreeArray);
void PreOrder();
void InOrder();
void PostOrder();
void reve();
void LevelOrder();
int ju(){
if(Root) return 1;
else return 0;
}
};
class que{
private:
BiTreeNode *ba[100];
int fro;
int rear;
public:
que(){
fro=rear=0;
}
void pop(){
fro++;
}
BiTreeNode *front(){
return ba[fro];
}
void push(BiTreeNode *t){
ba[rear]=t;
rear++;
}
int empty(){
if(rear==fro) return 1;
else return 0;
}
};
void BiTree::reve() {
if(Root==NULL) {
int i;
for(i=1; i<=4; i++)
cout<<"NULL"<<endl;
}
reve(Root);
}
void BiTree::reve(BiTreeNode *t) {
if(t==NULL) return ;
BiTreeNode *p1,*p2;
if(t->LeftChild||t->RightChild) {
p1=t->LeftChild;
t->LeftChild=t->RightChild;
t->RightChild=p1;
}
reve(t->LeftChild);
reve(t->RightChild);
}
void BiTree::LevelOrder() {
LevelOrder(Root);
}
void BiTree::LevelOrder(BiTreeNode *t) {
que tq;
BiTreeNode*p=t;
if(p) tq.push(p);
while(!tq.empty()){
p=tq.front();
tq.pop();
cout<<p->data<<' ';
if(p->LeftChild) tq.push(p->LeftChild);
if(p->RightChild) tq.push(p->RightChild);
}
}
void BiTree::CreateTree(string TreeArray) {
pos=0;
strTree.assign(TreeArray);
Root=CreateBiTree();
}
BiTreeNode* BiTree::CreateBiTree() {
BiTreeNode *T;
char ch;
ch=strTree[pos++];
if(ch=='#')
T=NULL;
else {
T=new BiTreeNode();
T->data=ch;
T->LeftChild=CreateBiTree();
T->RightChild=CreateBiTree();
}
return T;
}
void BiTree::PreOrder() {
PreOrder(Root);
}
void BiTree::PreOrder(BiTreeNode *t) {
if(t!=NULL) {
cout<<t->data<<' ';
PreOrder(t->LeftChild);
PreOrder(t->RightChild);
}
}
void BiTree::InOrder() {
InOrder(Root);
}
void BiTree::InOrder(BiTreeNode *t) {
if(t!=NULL) {
InOrder(t->LeftChild);
cout<<t->data<<' ';
InOrder(t->RightChild);
}
}
void BiTree::PostOrder() {
PostOrder(Root);
}
void BiTree::PostOrder(BiTreeNode *t) {
if(t!=NULL) {
PostOrder(t->LeftChild);
PostOrder(t->RightChild);
cout<<t->data<<' ';
}
}
int main(void) {
int t,i;
string str;
cin>>t;
while(t--) {
BiTree p;
cin>>str;
p.CreateTree(str);
p.reve();
p.PreOrder();
if(p.ju())
cout<<endl;
p.InOrder();
if(p.ju())
cout<<endl;
p.PostOrder();
if(p.ju())
cout<<endl;
p.LevelOrder();
if(p.ju())
cout<<endl;
}
return 0;
}
E. DS二叉树—二叉树结点的最大距离
题目描述
二叉树两个结点的距离是一个结点经过双亲结点,祖先结点等中间结点到达另一个结点经过的分支数。二叉树结点的最大距离是所有结点间距离的最大值。例如,下图所示二叉树结点最大距离是3,C和D的距离。
二叉树用先序遍历顺序创建,#表示空树。计算二叉树结点最大距离和最大距离的两个结点(假设二叉树中取最大距离的两个结点唯一)。
输入
测试次数T
第2行之后的T行,每行为一棵二叉树先序遍历结果(#表示空树)
输出
对每棵二叉树,输出树的结点最大距离和最大距离的结点,输出格式见样例。
输入样例1
3
A##
ABC##EF#G###D##
ABEH###F#K###
输出样例1
0:
5:G D
4:H K
代码
#include<bits/stdc++.h>
using namespace std;
struct BiTreeNode {
char data;
int depth;
BiTreeNode* lc, * rc;
BiTreeNode* parent;
};
int cnt;
string s;
BiTreeNode* CreateBiTree(int depth) {
if (cnt == s.length() || s[cnt] == '#') {
cnt++;
return NULL;
}
else {
BiTreeNode* t = new BiTreeNode;
t->data = s[cnt++];
t->depth = depth;
t->lc = CreateBiTree(depth + 1);
t->rc = CreateBiTree(depth + 1);
if (t->lc != NULL) t->lc->parent = t;
if (t->rc != NULL) t->rc->parent = t;
return t;
}
}
BiTreeNode* LCA(BiTreeNode* b1, BiTreeNode* b2) {
BiTreeNode* t1 = b1, * t2 = b2;
if (t1->depth < t2->depth)
swap(t1, t2);
while (t1->depth > t2->depth)
t1 = t1->parent;
while (t1 != t2) {
t1 = t1->parent;
t2 = t2->parent;
}
return t1;
}
BiTreeNode** Node;
int tot = 0;
void dfs(BiTreeNode* t) {
if (t == NULL) {
return;
}
Node[tot++] = t;
dfs(t->lc);
dfs(t->rc);
}
string str;
void InOrder(BiTreeNode* t) {
if (t == NULL) return;
InOrder(t->lc);
str += t->data;
InOrder(t->rc);
}
int main() {
int t;
cin >> t;
while (t--) {
cin >> s;
cnt = 0;
BiTreeNode* Root = CreateBiTree(1);
Node = new BiTreeNode * [1000];
tot = 0;
dfs(Root);
int maxn = 0;
char lc, rc;
for (int i = 0; i < tot; i++) {
for (int j = i + 1; j < tot; j++) {
BiTreeNode* lca = LCA(Node[i], Node[j]);
if (Node[i]->depth + Node[j]->depth - 2 * lca->depth > maxn) {
maxn = Node[i]->depth + Node[j]->depth - 2 * lca->depth;
lc = Node[i]->data;
rc = Node[j]->data;
}
}
}
cout << maxn << ':';
if (maxn != 0) {
str = "";
InOrder(Root);
for (int i = 0; i < str.length(); i++) {
if (str[i] == lc) {
cout << lc << ' ' << rc << endl;
break;
}
if (str[i] == rc) {
cout << rc << ' ' << lc << endl;
break;
}
}
}
else
cout << endl;
}
return 0;
}