下周考试有点多~~~,先放
目录
A二叉树非递归前序遍历
题目描述
用二叉树的带虚结点表示的前序遍历序可以唯一的确定一棵二叉树,请用非递归算法实现二叉树的前序遍历。
输入格式
每行是一棵二叉树的带虚结点(#)表示的前序遍历序串,长度不超过2000。每个结点为一个小写字母或一个数字。
输出格式
对每行输入,分别用递归和非递归两种算法输出对应二叉树的前序遍历序(不含虚结点)
输入样例 复制
ab##c##
#
ab###
输出样例 复制
abc
abc
ab
ab
code
#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<queue>
#include<stack>
using namespace std;
struct BiNode
{
char data;
BiNode *lchild,*rchild;
};
typedef BiNode *BiTree;
int InitBiTree(BiTree &T){
T=NULL;
return 0;
}
string PreTraverse_nonRec(BiTree T){
string result="";
if(T==NULL)return result;
BiTree p=T;
stack<BiTree>s;
// s.push(p);
while(p||!s.empty()){
if(p){
s.push(p);
result+=p->data;
p=p->lchild;
}
else{
BiTree t=s.top();
s.pop();
p=t->rchild;
}
}
return result;
}
char *CreateBiTree(BiTree &T,char *str){
if(*str=='#'){
T=NULL;
return str+1;
}
//创建节点
T=new BiNode;
T->data=*str;
char *strAfterLeft=CreateBiTree(T->lchild,str+1);
char *strAfterRight=CreateBiTree(T->rchild,strAfterLeft);
//返回剩余的字符串
return strAfterRight;
}
int PreTraverse(BiTree T){
if(T==NULL)return 0;
cout<<T->data;
PreTraverse(T->lchild);
PreTraverse(T->rchild);
return 0;
}
int DestroyBiTree(BiTree&T){
if(T==NULL){
return 0;
}
DestroyBiTree(T->lchild);
DestroyBiTree(T->rchild);
delete T;
T=NULL;
return 0;
}
B二叉树非递归中序遍历
题目描述
用二叉树的带虚结点表示的前序遍历序可以唯一的确定一棵二叉树,请用非递归算法实现二叉树的中序遍历。
输入格式
每行是一棵二叉树的带虚结点(#)表示的前序遍历序串,长度不超过2000。每个结点为一个小写字母或一个数字。
输出格式
对每行输入,分别用递归和非递归两种算法输出对应二叉树的中序遍历序(不含虚结点)
输入样例 复制
ab##c##
#
ab###
输出样例 复制
bac
bac
ba
ba
code
#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<queue>
#include<stack>
using namespace std;
struct BiNode
{
char data;
BiNode *lchild,*rchild;
};
typedef BiNode *BiTree;
int InitBiTree(BiTree &T){
T=NULL;
return 0;
}
string PreTraverse_nonRec(BiTree T){
string result="";
if(T==NULL)return result;
BiTree p=T;
stack<BiTree>s;
// s.push(p);
while(p||!s.empty()){
if(p){
s.push(p);
result+=p->data;
p=p->lchild;
}
else{
BiTree t=s.top();
s.pop();
p=t->rchild;
}
}
return result;
}
string InTraverse_nonRec(BiTree T){
string result="";
if(T==NULL)return result;
BiTree p=T;
stack<BiTree>s;
// s.push(p);
while(p||!s.empty()){
if(p){
s.push(p);
p=p->lchild;
}
else{
BiTree t=s.top();
result+=t->data;
s.pop();
p=t->rchild;
}
}
return result;
}
char *CreateBiTree(BiTree &T,char *str){
if(*str=='#'){
T=NULL;
return str+1;
}
//创建节点
T=new BiNode;
T->data=*str;
char *strAfterLeft=CreateBiTree(T->lchild,str+1);
char *strAfterRight=CreateBiTree(T->rchild,strAfterLeft);
//返回剩余的字符串
return strAfterRight;
}
int PreTraverse(BiTree T){
if(T==NULL)return 0;
cout<<T->data;
PreTraverse(T->lchild);
PreTraverse(T->rchild);
return 0;
}
int InTraverse(BiTree T){
if(T==NULL)return 0;
InTraverse(T->lchild);
cout<<T->data;
InTraverse(T->rchild);
return 0;
}
int DestroyBiTree(BiTree&T){
if(T==NULL){
return 0;
}
DestroyBiTree(T->lchild);
DestroyBiTree(T->rchild);
delete T;
T=NULL;
return 0;
}
/*int main(){
char str[2000];
while(cin>>str){
BiTree tree;
InitBiTree(tree);
CreateBiTree(tree,str);
InTraverse(tree);
cout<<endl;
string result=InTraverse_nonRec(tree);
cout<<result<<endl;
DestroyBiTree(tree);
}
return 0;
}*/
C二叉树非递归后序遍历
题目描述
用二叉树的带虚结点表示的前序遍历序可以唯一的确定一棵二叉树,请用非递归算法实现二叉树的后序遍历。
输入格式
每行是一棵二叉树的带虚结点(#)表示的前序遍历序串,长度不超过2000。每个结点为一个小写字母或一个数字。
输出格式
对每行输入,分别用递归和非递归两种算法输出对应二叉树的后序遍历序(不含虚结点)
输入样例 复制
ab##c##
#
ab###
输出样例 复制
bca
bca
ba
ba
code:这个思路是先跟右左的顺序遍历,然后逆序就好啦
#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<queue>
#include<stack>
#include<algorithm>
using namespace std;
struct BiNode
{
char data;
BiNode *lchild,*rchild;
};
typedef BiNode *BiTree;
int InitBiTree(BiTree &T){
T=NULL;
return 0;
}
string PreTraverse_nonRec(BiTree T){
string result="";
if(T==NULL)return result;
BiTree p=T;
stack<BiTree>s;
// s.push(p);
while(p||!s.empty()){
if(p){
s.push(p);
result+=p->data;
p=p->lchild;
}
else{
BiTree t=s.top();
s.pop();
p=t->rchild;
}
}
return result;
}
string InTraverse_nonRec(BiTree T){
string result="";
if(T==NULL)return result;
BiTree p=T;
stack<BiTree>s;
// s.push(p);
while(p||!s.empty()){
if(p){
s.push(p);
p=p->lchild;
}
else{
BiTree t=s.top();
result+=t->data;
s.pop();
p=t->rchild;
}
}
return result;
}
char *CreateBiTree(BiTree &T,char *str){
if(*str=='#'){
T=NULL;
return str+1;
}
//创建节点
T=new BiNode;
T->data=*str;
char *strAfterLeft=CreateBiTree(T->lchild,str+1);
char *strAfterRight=CreateBiTree(T->rchild,strAfterLeft);
//返回剩余的字符串
return strAfterRight;
}
int PreTraverse(BiTree T){
if(T==NULL)return 0;
cout<<T->data;
PreTraverse(T->lchild);
PreTraverse(T->rchild);
return 0;
}
int InTraverse(BiTree T){
if(T==NULL)return 0;
InTraverse(T->lchild);
cout<<T->data;
InTraverse(T->rchild);
return 0;
}
string SucTraverse_nonRec(BiTree T){
string result="";
BiTree p=T;
stack<BiTree>s;
while(p||!s.empty()){
if(p){
s.push(p);
result+=p->data;
p=p->rchild;
}
else {
BiTree t=s.top();
//result+=t->data;
s.pop();
p=t->lchild;
}
}
reverse(result.begin(),result.end());
return result;
}
int SucTraverse(BiTree T){
if(T==NULL)return 0;
SucTraverse(T->lchild);
SucTraverse(T->rchild);
cout<<T->data;
return 0;
}
int DestroyBiTree(BiTree&T){
if(T==NULL){
return 0;
}
DestroyBiTree(T->lchild);
DestroyBiTree(T->rchild);
delete T;
T=NULL;
return 0;
}
/*int main(){
char str[2000];
while(cin>>str){
BiTree tree;
InitBiTree(tree);
CreateBiTree(tree,str);
SucTraverse(tree);
cout<<endl;
string result=SucTraverse_nonRec(tree);
cout<<result<<endl;
DestroyBiTree(tree);
}
return 0;
}*/
D求二叉树根节点的下标
题目描述
用一棵二叉树的前序遍历序和中序遍历序可以唯一确定一棵二叉树,这个算法的核心操作是根据前序遍历序,查找中序遍历序中根节点的位置,以确定左子树序列,根节点,和右子树序列。然后递归找到每个子树的根节点就可以完成二叉树的构造。
输入格式
每行输入为一棵非空二叉树的前序遍历序串和中序遍历序串(两串长度均不超过2000),前序遍历序和中序遍历序中间用一个空格隔开。 每个结点为一个字符(字母或数字),且不存在相同结点。
输出格式
对每行输入,输出根节点在中序遍历序列中的下标
输入样例 复制
abc bac
ab ba
输出样例 复制
1
1
code:
int main(){
string a,b;
while(cin>>a>>b){
for(int i=0;i<b.size();i++){
if(b[i]==a[0]){
cout<<i<<endl;
break;
}
}
}
}
E: 根据前序+中序还原二叉树
题目描述
用一棵二叉树的前序遍历序和中序遍历序可以唯一确定一棵二叉树。
输入格式
每行输入为一棵非空二叉树的前序遍历序串和中序遍历序串(两串长度均不超过2000),前序遍历序和中序遍历序中间用一个空格隔开。 每个结点为一个字符(字母或数字),且不存在相同结点。
输出格式
对每行输入,输出对应二叉树的后序遍历序后换行
输入样例 复制
abc bac
ab ba
输出样例 复制
bca
ba
code:
#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<queue>
#include<stack>
#include<algorithm>
using namespace std;
struct BiNode
{
char data;
BiNode *lchild,*rchild;
};
typedef BiNode *BiTree;
int InitBiTree(BiTree &T){
T=NULL;
return 0;
}
string PreTraverse_nonRec(BiTree T){
string result="";
if(T==NULL)return result;
BiTree p=T;
stack<BiTree>s;
// s.push(p);
while(p||!s.empty()){
if(p){
s.push(p);
result+=p->data;
p=p->lchild;
}
else{
BiTree t=s.top();
s.pop();
p=t->rchild;
}
}
return result;
}
string InTraverse_nonRec(BiTree T){
string result="";
if(T==NULL)return result;
BiTree p=T;
stack<BiTree>s;
// s.push(p);
while(p||!s.empty()){
if(p){
s.push(p);
p=p->lchild;
}
else{
BiTree t=s.top();
result+=t->data;
s.pop();
p=t->rchild;
}
}
return result;
}
char *CreateBiTree(BiTree &T,char *str){
if(*str=='#'){
T=NULL;
return str+1;
}
//创建节点
T=new BiNode;
T->data=*str;
char *strAfterLeft=CreateBiTree(T->lchild,str+1);
char *strAfterRight=CreateBiTree(T->rchild,strAfterLeft);
//返回剩余的字符串
return strAfterRight;
}
int PreTraverse(BiTree T){
if(T==NULL)return 0;
cout<<T->data;
PreTraverse(T->lchild);
PreTraverse(T->rchild);
return 0;
}
int InTraverse(BiTree T){
if(T==NULL)return 0;
InTraverse(T->lchild);
cout<<T->data;
InTraverse(T->rchild);
return 0;
}
string SucTraverse_nonRec(BiTree T){
string result="";
BiTree p=T;
stack<BiTree>s;
while(p||!s.empty()){
if(p){
s.push(p);
result+=p->data;
p=p->rchild;
}
else {
BiTree t=s.top();
//result+=t->data;
s.pop();
p=t->lchild;
}
}
reverse(result.begin(),result.end());
return result;
}
int SucTraverse(BiTree T){
if(T==NULL)return 0;
SucTraverse(T->lchild);
SucTraverse(T->rchild);
cout<<T->data;
return 0;
}
int DestroyBiTree(BiTree&T){
if(T==NULL){
return 0;
}
DestroyBiTree(T->lchild);
DestroyBiTree(T->rchild);
delete T;
T=NULL;
return 0;
}
/*int restroreBitree(BiTree &T,string a,string b){
if(a.size()==0||b.size()==0)return 0;
T=new BiNode;
T->data=a[0];
int p=0;
while(p<b.size()&&b[p]!=a[0])p++;
restroreBitree(T->lchild,a.substr(1,p),b.substr(0,p));
restroreBitree(T->rchild,a.substr(p+1),b.substr(p+1));
return 0;
}*/
BiTree restoreBitree(char *pre,char *mid,int len){
if(len==0)return NULL;
char ch=pre[0];
int index=0;
while(mid[index]!=ch){
index++;
}
BiTree T=new BiNode;
T->data=ch;
T->lchild=restoreBitree(pre+1,mid,index);
T->rchild=restoreBitree(pre+index+1,mid+index+1,len-index-1);
return T;
}
int main(){
char a[2000],b[2000];
while(cin>>a>>b){
BiTree tree=restoreBitree(a,b,strlen(a));
SucTraverse(tree);
cout<<endl;
DestroyBiTree(tree);
}
return 0;
}
F: 算法6-12:自底向上的赫夫曼编码
题目描述
在通讯领域,经常需要将需要传送的文字转换成由二进制字符组成的字符串。在实际应用中,由于总是希望被传送的内容总长尽可能的短,如果对每个字符设计长度不等的编码,且让内容中出现次数较多的字符采用尽可能短的编码,则整个内容的总长便可以减少。另外,需要保证任何一个字符的编码都不是另一个字符的编码前缀,这种编码成为前缀编码。
而赫夫曼编码就是一种二进制前缀编码,在本题中,读入n个字符所对应的权值,生成赫夫曼编码,并依次输出计算出的每一个赫夫曼编码。
输入格式
输入的第一行包含一个正整数n,表示共有n个字符需要编码。其中n不超过100。 第二行中有n个用空格隔开的正整数,分别表示n个字符的权值。
输出格式
共n行,每行一个字符串,表示对应字符的赫夫曼编码。
输入样例 复制
8
5 29 7 8 14 23 3 11
输出样例 复制
0110
10
1110
1111
110
00
0111
010
数据范围与提示
满足条件的哈夫曼树不止一种。为了确保答案唯一,题目的测试数据约定,合并两个节点时,先出现的节点(也就是数组中下标小的节点)为左子;
code:
#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<queue>
#include<stack>
#include<algorithm>
using namespace std;
const int inf=0x3f3f3f3f;
typedef struct{
int wight;
int parent;
int lchild;
int rchild;
}HTNode,*HuffumanTree;
void Select(HTNode HT[],int n,int *s1,int *s2){
int m1=inf,m2=inf;
for(int i=1;i<=n;i++){
if(HT[i].wight<m1&&HT[i].parent==-1){
m1=HT[i].wight;
*s1=i;
}
}
HT[*s1].parent=1;
for(int i=1;i<=n;i++){
if(HT[i].wight<m2&&HT[i].parent==-1){
m2=HT[i].wight;
*s2=i;
}
}
HT[*s2].parent=1;
int t;
if(*s1>*s2){
t=*s1;
*s1=*s2;
*s2=t;
}
}
void HuffumanCoding(int *w,int n){
if(n<=1){
return ;
}
int m=2*n-1;
HTNode HT[m+1];
HuffumanTree p;
int i;
for( p=&HT[1],i=1;i<=n;i++,p++,w++){
p->wight=*w;
p->lchild=-1;
p->rchild=-1;
p->parent=-1;
}
for(;i<=m;i++,p++){
p->lchild=-1;
p->rchild=-1;
p->parent=-1;
p->wight=0;
}
int s1=0,s2=0;
for(int i=n+1;i<=m;i++){
Select(HT,i-1,&s1,&s2);
HT[s1].parent=i;
HT[s2].parent=i;
HT[i].lchild=s1;
HT[i].rchild=s2;
HT[i].wight=HT[s1].wight+HT[s2].wight;
}
char HC[n+1][n];
for(int i=1;i<=n;i++){
char cd[n];
cd[n-1]='\0';
int start=n-1,c,f;
for(c=i,f=HT[i].parent;f!=-1;c=f,f=HT[c].parent){
if(HT[f].lchild==c){
start--;
cd[start]='0';
}
else {
start--;
cd[start]='1';
}
}
strcpy(HC[i],&cd[start]);
}
for(int j=1;j<=n;j++){
printf("%s",HC[j]);
cout<<endl;
}
}
int main(){
int n;
cin>>n;
int a[n+2];
for(int i=0;i<n;i++)cin>>a[i];
int *w=&a[0];
HuffumanCoding(w,n);
}
G: 视频合并问题
题目描述
有多个视频需要合并为一个视频,假设一次只能将两个视频进行合并,合并需要的时间为该两个视频的时间之和。请计算将多个视频合并为一个视频需要的最小时间为多少?
输入格式
输入的第一行包含一个正整数n,表示共有n个视频需要合并。其中n不超过100。 第二行中有n个用空格隔开的正整数,分别表示n个视频的时间。
输出格式
输出包括一个正整数,即合并需要的最小时间。
输入样例 复制
8
5 29 7 8 14 23 3 11
输出样例 复制
271
code:
int main(){
int n;
cin>>n;
int a[n+5];
priority_queue<int,vector<int>,greater<int> >pq;
while(n--){
int x;
cin>>x;
pq.push(x);
}
int ans=0;
while(pq.size()>=2){
int a=pq.top();
pq.pop();
int b=pq.top();
pq.pop();
ans+=(a+b);
// cout<<a+b<<endl;
pq.push(a+b);
}
cout<<ans<<endl;
}
H: 二叉树实现的简单物种识别系统-附加代码模式
题目描述
用二叉树可以实现一个简单的物种识别系统,举例如下:
请编写代码根据上面的系统完成物种识别过程。注意问题对应的左节点表示回答的是no,右节点表示回答的yes
输入格式
输入包括两行,分别是每个问题的回答,y或者Y表示yes,n或者N表示no
输出格式
输出对应的物种识别结果
输入样例 复制
y
y
输出样例 复制
the answer is:eagle
code:
#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<queue>
#include<stack>
#include<algorithm>
#include<bits/stdc++.h>
using namespace std;
const int inf=0x3f3f3f3f;
typedef struct{
int wight;
int parent;
int lchild;
int rchild;
}HTNode,*HuffumanTree;
void Select(HTNode HT[],int n,int *s1,int *s2){
int m1=inf,m2=inf;
for(int i=1;i<=n;i++){
if(HT[i].wight<m1&&HT[i].parent==-1){
m1=HT[i].wight;
*s1=i;
}
}
HT[*s1].parent=1;
for(int i=1;i<=n;i++){
if(HT[i].wight<m2&&HT[i].parent==-1){
m2=HT[i].wight;
*s2=i;
}
}
HT[*s2].parent=1;
/*int t;
if(*s1>*s2){
t=*s1;
*s1=*s2;
*s2=t;
}*/
}
void HuffumanCoding(int *w,int n){
if(n<=1){
return ;
}
int m=2*n-1;
HTNode HT[m+1];
HuffumanTree p;
int i;
for( p=&HT[1],i=1;i<=n;i++,p++,w++){
p->wight=*w;
p->lchild=-1;
p->rchild=-1;
p->parent=-1;
}
for(;i<=m;i++,p++){
p->lchild=-1;
p->rchild=-1;
p->parent=-1;
p->wight=0;
}
int s1=0,s2=0;
for(int i=n+1;i<=m;i++){
Select(HT,i-1,&s1,&s2);
HT[s1].parent=i;
HT[s2].parent=i;
HT[i].lchild=s1;
HT[i].rchild=s2;
HT[i].wight=HT[s1].wight+HT[s2].wight;
}
char HC[n+1][n];
for(int i=1;i<=n;i++){
char cd[n];
cd[n-1]='\0';
int start=n-1,c,f;
for(c=i,f=HT[i].parent;f!=-1;c=f,f=HT[c].parent){
if(HT[f].lchild==c){
start--;
cd[start]='0';
}
else {
start--;
cd[start]='1';
}
}
strcpy(HC[i],&cd[start]);
}
for(int j=1;j<=n;j++){
printf("%s",HC[j]);
cout<<endl;
}
}
struct BiNode{
string data;
BiNode *lchild,*rchild;
};
typedef BiNode *BiTree;
int InitBiTree(BiTree &T){
T=NULL;
return 0;
}
BiNode *StartRecognize(BiTree T){
BiNode *p=T;
for(int i=0;i<2;i++){
char c;
cin>>c;
if(c=='n'||c=='N')p=p->lchild;
else p=p->rchild;
}
return p;
}
BiNode *getNode(string data){
BiNode *node=new BiNode();
node->data=data;
node->lchild=node->rchild=nullptr;
return node;
}
/*BiTree setRecognizeSystem(){
BiTree T=getNode("Can it fly?");
BiNode *n1=getNode("Is it dangerous");
BiNode *n2=getNode("Does it eat meat?");
BiNode *n3=getNode("rabbit");
BiNode *n4=getNode("tiger");
BiNode *n5=getNode("swallow");
BiNode *n6=getNode("eagle");
T->lchild=n1;
T->rchild=n2;
n1->lchild=n3;
n1->rchild=n4;
n2->rchild=n5;
n2->rchild=n6;
return T;
}
int main(){
BiTree T=setRecognizeSystem();
BiNode *p=StartRecognize(T);
if(p)cout<<"the answer is:"<<p->data<<endl;
}*/
I: 静态链表存储的二叉树查找根节点
题目描述
用数组模拟实现链表的功能,即静态链表,也可以用来存储二叉树。
请编写程序,输出静态链表存储的二叉树的根节点
输入格式
输入给出2棵二叉树树的信息。
对于每棵树,首先在一行中给出一个非负整数N (≤10),即该树的结点数(此时假设结点从0到N−1编号);
随后N行,第i行对应编号第i个结点,给出该结点中存储的1个英文大写字母、其左孩子结点的编号、右孩子结点的编号。
如果孩子结点为空,则在相应位置上给出“-”。
给出的数据间用一个空格分隔。
注意:题目保证每个结点中存储的字母是不同的。
输出格式
针对每颗二叉树,输出根节点。
如果二叉树为空,则输出空行。
输入样例 复制
8
A 1 2
B 3 4
C 5 -
D - -
E 6 -
G 7 -
F - -
H - -
8
G - 4
B 7 6
F - -
A 5 1
H - -
C 0 -
D - -
E 2 -
输出样例 复制
A
A
code:
int main(){
for(int k=0;k<2;k++){
int n;
string s="";
cin>>n;
char c;
char a,b;
bool isok[n+5];
memset(isok,false,sizeof isok);
for(int i=0;i<n;i++){
cin>>c>>a>>b;
s.push_back(c);
if(a>='0'&&a<='9'){
isok[a-'0']=true;
// cout<<a<<endl;
}
if(b>='0'&&b<='9')isok[b-'0']=true;
}
for(int i=0;i<n;i++){
if(!isok[i]){
cout<<s[i]<<endl;
break;
}
// cout<<isok[i]<<endl;
}
}
}
J: 基础实验4-2.1:树的同构
题目描述
给定两棵树T1和T2。如果T1可以通过若干次左右孩子互换就变成T2,则我们称两棵树是“同构”的。例如图1给出的两棵树就是同构的,因为我们把其中一棵树的结点A、B、G的左右孩子互换后,就得到另外一棵树。而图2就不是同构的。
现给定两棵树,请你判断它们是否是同构的。
输入格式
输入给出2棵二叉树树的信息。对于每棵树,首先在一行中给出一个非负整数N (≤10),即该树的结点数(此时假设结点从0到N−1编号);随后N行,第i行对应编号第i个结点,给出该结点中存储的1个英文大写字母、其左孩子结点的编号、右孩子结点的编号。如果孩子结点为空,则在相应位置上给出“-”。给出的数据间用一个空格分隔。注意:题目保证每个结点中存储的字母是不同的。
输出格式
如果两棵树是同构的,输出“Yes”,否则输出“No”。
输入样例 复制
8
A 1 2
B 3 4
C 5 -
D - -
E 6 -
G 7 -
F - -
H - -
8
G - 4
B 7 6
F - -
A 5 1
H - -
C 0 -
D - -
E 2 -
输出样例 复制
Yes
数据范围与提示
可以用递归算法求解,判定规则如下:
(1)如果两棵树都为空,同构;
(2)一棵树为空,另一棵树不为空,不同构;
(3)两棵树都不为空,但根节点数据不同,不同构;
(4)两棵树的左子树都为空,则判断右子树是否同构;
(5)两棵树的左子树都不为空,且左子树的根节点值相等,判断两棵树的左子树是否同构,以及两棵树的右子树是否同构;
(6)两棵树的左右子树有一个为空,或者皆不为空但根节点不相等,需要判断一棵树的左/右子树和另一棵树的右/左子树是否同构;
code:
#include<bits/stdc++.h>
using namespace std;
typedef struct BiNode{
char data;
int lchild,rchild;
}Tree;
#define null -1
int InitTree(Tree *T){
int n,flag[10]={0};//flag标记子树,若为1,则是子树;为0则是根
cin>>n;
if(!n)return -1;
for(int i=0;i<n;i++){
char l,r;
cin>>T[i].data>>l>>r;
if(l=='-')T[i].lchild=null;
else {
T[i].lchild=(l-'0');
flag[l-'0']=1;
}
if(r=='-')T[i].rchild=null;
else {
T[i].rchild=r-'0';
flag[r-'0']=1;
}
}
for(int i=0;i<n;i++){
if(!flag[i])return i;
}
return null;
}
bool isempty(Tree T){
if(T.lchild==null&&T.rchild==null)return 1;
return 0;
}
bool issame(Tree T1[],int i,Tree T2[],int j){
if(i==-1&&j!=-1)return 0;
if(i!=-1&&j==-1)return 0;
if(i==-1&&j==-1)return 1;
//if(isempty(T1[i])&&isempty(T2[j])&&T1[i].data==T2[j].data)return true;
if(T1[i].data==T2[j].data){
return (issame(T1,T1[i].lchild,T2,T2[j].lchild)&&issame(T1,T1[i].rchild,T2,T2[j].rchild)||(issame(T1,T1[i].lchild,T2,T2[j].rchild)&&issame(T1,T1[i].rchild,T2,T2[j].lchild)));
}
return false;
}
int main(){
Tree T1[15],T2[15];
int root1,root2;
root1=InitTree(T1);
root2=InitTree(T2);
// cout<<root1<<" "<<root2<<endl;
if(issame(T1,root1,T2,root2))cout<<"Yes"<<endl;
else cout<<"No"<<endl;
return 0;
}
K: 哈夫曼树--查找值最小的两个叶节点
题目描述
哈夫曼树的构造过程,最重要的是找到值最小的两个叶节点。
输入格式
输入第一行为整数n(n大于2且小于100),表示哈夫曼树的叶节点个数
接下来一行为n个整数,表示哈夫曼树的每个叶节点的值
输出格式
输出值最小的两个叶节点的下标。如果存在值相同的叶节点,优先输出下标小的节点。
输入样例 复制
8
5 29 7 8 14 23 3 11
输出样例 复制
6 0
code:
#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<queue>
#include<stack>
#include<algorithm>
#include<bits/stdc++.h>
using namespace std;
const int inf=0x3f3f3f3f;
typedef struct{
int wight;
int parent;
int lchild;
int rchild;
}HTNode,*HuffumanTree;
void Select(HTNode HT[],int n,int *s1,int *s2){
int m1=inf,m2=inf;
for(int i=1;i<=n;i++){
if(HT[i].wight<m1&&HT[i].parent==-1){
m1=HT[i].wight;
*s1=i;
}
}
HT[*s1].parent=1;
for(int i=1;i<=n;i++){
if(HT[i].wight<m2&&HT[i].parent==-1){
m2=HT[i].wight;
*s2=i;
}
}
HT[*s2].parent=1;
/*int t;
if(*s1>*s2){
t=*s1;
*s1=*s2;
*s2=t;
}*/
}
void HuffumanCoding(int *w,int n){
if(n<=1){
return ;
}
int m=2*n-1;
HTNode HT[m+1];
HuffumanTree p;
int i;
for( p=&HT[1],i=1;i<=n;i++,p++,w++){
p->wight=*w;
p->lchild=-1;
p->rchild=-1;
p->parent=-1;
}
for(;i<=m;i++,p++){
p->lchild=-1;
p->rchild=-1;
p->parent=-1;
p->wight=0;
}
int s1=0,s2=0;
for(int i=n+1;i<=m;i++){
Select(HT,i-1,&s1,&s2);
HT[s1].parent=i;
HT[s2].parent=i;
HT[i].lchild=s1;
HT[i].rchild=s2;
HT[i].wight=HT[s1].wight+HT[s2].wight;
}
char HC[n+1][n];
for(int i=1;i<=n;i++){
char cd[n];
cd[n-1]='\0';
int start=n-1,c,f;
for(c=i,f=HT[i].parent;f!=-1;c=f,f=HT[c].parent){
if(HT[f].lchild==c){
start--;
cd[start]='0';
}
else {
start--;
cd[start]='1';
}
}
strcpy(HC[i],&cd[start]);
}
for(int j=1;j<=n;j++){
printf("%s",HC[j]);
cout<<endl;
}
}
int main(){
int n;
cin>>n;
int a[n+5];
bool isok[n+5];
memset(isok,false,sizeof isok);
for(int i=0;i<n;i++)cin>>a[i];
int m1=inf,m2=inf;
int p1,p2;
for(int i=0;i<n;i++){
if(m1>a[i]){
p1=i;
m1=a[i];
}
}
for(int i=0;i<n;i++){
if(m2>a[i]&&i!=p1){
p2=i;
m2=a[i];
}
}
cout<<p1<<" "<<p2;
}
L: 静态链表存储的二叉树的非递归遍历算法-附加代码模式
题目描述
用数组模拟实现链表的功能,即静态链表,也可以用来存储二叉树。
请编写程序,用非递归遍历算法输出静态链表存储前中后三种遍历结果。
输入格式
输入给出2棵二叉树树的信息。
对于每棵树,首先在一行中给出一个非负整数N (≤10),即该树的结点数(此时假设结点从0到N−1编号);
随后N行,第i行对应编号第i个结点,给出该结点中存储的1个英文大写字母、其左孩子结点的编号、右孩子结点的编号。
如果孩子结点为空,则在相应位置上给出“-”。
给出的数据间用一个空格分隔。
注意:题目保证每个结点中存储的字母是不同的。
输出格式
针对每颗二叉树,输出3行,分别是前中后三种序列的遍历结果。
如果二叉树为空,则输出3个空行。
输入样例 复制
8
A 1 2
B 3 4
C 5 -
D - -
E 6 -
G 7 -
F - -
H - -
8
G - 4
B 7 6
F - -
A 5 1
H - -
C 0 -
D - -
E 2 -
输出样例 复制
ABDEFCGH
DBFEAHGC
DFEBHGCA
ACGHBEFD
GHCAFEBD
HGCFEDBA
code:
#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<queue>
#include<stack>
#include<algorithm>
using namespace std;
struct BiNode{
char data;
char lchild;
char rchild;
};
struct BiTree{
int nodeNumber;//节点总数
BiNode data[10];//节点数目
int rootIndex;//根节点下标
};
//遍历所有节点,确定根节点下标
void FindRootIndex(BiTree &T){
int n=T.nodeNumber;
int flag[n+5];
memset(flag,0,sizeof(flag));
for(int i=0;i<n;i++){
if(T.data[i].lchild!='-')
flag[T.data[i].lchild-'0']=1;
if(T.data[i].rchild!='-')
flag[T.data[i].rchild-'0']=1;
}
for(int i=0;i<n;i++)if(!flag[i]){T.rootIndex=i;
return ;}
}
//获取前序遍历结果字符串
string getPreTraverseStr(const BiTree &T){
string str="";
if(T.nodeNumber==0)return str;
stack<BiNode>s;
char p=T.rootIndex+'0';
while(p!='-'||!s.empty()){
if(p!='-'){
s.push(T.data[p-'0']);
p=T.data[p-'0'].lchild;
str.push_back(s.top().data);
}
else{
BiNode t=s.top();
s.pop();
p=t.rchild;
}
}
return str;
}
//获取中序遍历结果字符串
string getInTraverseStr(const BiTree &T){
string str="";
if(T.nodeNumber==0)return str;
stack<BiNode>s;
char p=T.rootIndex+'0';
while(p!='-'||!s.empty()){
if(p!='-'){
s.push(T.data[p-'0']);
p=T.data[p-'0'].lchild;
}
else{
str.push_back(s.top().data);
BiNode t=s.top();
s.pop();
p=t.rchild;
}
}
return str;
}
//获取后序遍历结果字符串
string getSucTraverseStr(const BiTree &T){
string str="";
if(T.nodeNumber==0)return str;
stack<BiNode>s;
char p=T.rootIndex+'0';
while(p!='-'||!s.empty()){
if(p!='-'){
s.push(T.data[p-'0']);
p=T.data[p-'0'].rchild;
str.push_back(s.top().data);
}
else{
BiNode t=s.top();
s.pop();
p=t.lchild;
}
}
reverse(str.begin(),str.end());
return str;
}
/*void InputBiTree(BiTree &T){
cin>>T.nodeNumber;
for(int i=0;i<T.nodeNumber;i++){
cin>>T.data[i].data>>T.data[i].lchild>>T.data[i].rchild;
}
}
int main(){
BiTree T;
InputBiTree(T);
FindRootIndex(T);
string str=getPreTraverseStr(T);
cout<<str<<endl;
str=getInTraverseStr(T);
cout<<str<<endl;
str=getSucTraverseStr(T);
cout<<str<<endl;
InputBiTree(T);
FindRootIndex(T);
str=getPreTraverseStr(T);
cout<<str<<endl;
str=getInTraverseStr(T);
cout<<str<<endl;
str=getSucTraverseStr(T);
cout<<str<<endl;
return 0;
}*/
终于搞完了,文字以后有空再加,又熬夜了~。