百花11/3-11/8数据结构作业

下周考试有点多~~~,先放

目录

A二叉树非递归前序遍历

B二叉树非递归中序遍历

C二叉树非递归后序遍历

 D求二叉树根节点的下标

E: 根据前序+中序还原二叉树

 F: 算法6-12:自底向上的赫夫曼编码

 G: 视频合并问题

 H: 二叉树实现的简单物种识别系统-附加代码模式

 I: 静态链表存储的二叉树查找根节点

J: 基础实验4-2.1:树的同构 

 K: 哈夫曼树--查找值最小的两个叶节点

 L: 静态链表存储的二叉树的非递归遍历算法-附加代码模式 


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;
}*/

终于搞完了,文字以后有空再加,又熬夜了~。 

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值