uva122 二叉树的实现和层次遍历(bfs)

题目见紫书

6.3.2 二叉树的层次遍历

1.二叉树的实现:

a.用指针实现:用结构体记录结点,利用指针访问结点

其中变量left,right的值 new的返回值都是地址

/*二叉树的结点定义和操作*/
//结点类型
struct Node{
    bool have_value;                       //是否被赋值过
    int v;                                 //结点值
    Node *left,*right;
    Node():v(-1),have_value(false),left(NULL),right(NULL){}//构造函数 
}; 
Node* newnode(){return new Node()};        //申请新结点的函数 

b.用数组实现:

  计数器cnt为已存在的节点数(编号最大值),用编号代替地址访问结点,用数组 [编号]来访问节点,其中left[u],right[u]都是记录的编号,结构体中的成员变量成了全局数组。

int newnode(){
    int u=++cnt;
    left[u]=right[u]=0;
    have_value[root]=false;
    return u;
}

其中指针是利用动态内存实现,需要一直申请新内存(new),为防止内存泄漏,需要释放内存

Node* newnode(){return new Node()};        //申请新结点的函数 

而数组是静态内存实现,编程简单,容易调试,不需释放动态内存,只要重置结点计数器和根结点的左有子树就行了.

可以用静态数组配合空闲列表实现一个简单的内存池,防止内存溢出(不太懂,先不学,以后再看,紫书154页)

二叉树的bfs要用队列来实现

//二叉树的bfs
bool bfs(vector<int>& ans){
    queue<Node*> q;
    ans.clear();
    q.push(root);                          //初始时只有一个根结点
    while(!q.empty()){
        Node* u=q.front(); q.pop();
        if(!u->have_value) return false;   //有结点未被赋值,输入有误 
        ans.push_back(u->v);               //增加到输出序列的尾部 
        if(u->left!=NULL) q.push(u->left); //如果有左节点,放入队列 
        if(u->right !=NULL) q.push(u->right);//如果有右结点,放入序列 
    } 
    return true;                           //输入正确 
}

其他:

· 可以用new运算符申请空间并执行构造函数。如果返回值为NULL,说明空间不足,申请失败。

·  strchr

strchr是计算机编程语言的一个函数,原型为extern char *strchr(const char *s,char c),可以查找字符串s中首次出现字符c的位置。

指针实现如下:

注: u->v 其中u是结构指针;

         任何指针都不能为空指针!包括结构指针 Node * root; 若无root=newnode(); root就是空指针,错都不知道错到哪了;

       if(!strcmp(s,"()"))break;字符串比较就这样比较

//二叉树的动态实现与层次遍历
//new和delete是运算符,没有头文件 
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<vector>
#include<queue>
using namespace std;
const int maxn=256+10;

bool failed;
struct Node{
    bool have_valued;
    int v;
    Node* left,*right;
    Node():have_valued(false),left(NULL),right(NULL){};
};
Node* root;                                           // 此时root为空指针 
Node* newnode(){return new Node;}
bool addnode(int v,char* s){
    Node* u=root;
    int n=strlen(s);
    for(int i=0;i<n;i++)
    if(s[i]=='L'){if(u->left==NULL)u->left=newnode();
    u=u->left;
    }
    else if(s[i]=='R'){if(u->right==NULL)u->right=newnode();
    u=u->right;
    }
    if(u->have_valued)failed=true;
    else u->v=v;
    u->have_valued=true;
    return true;
}
void remove(Node* u){
    if(u==NULL)return;
    if(u->right!=NULL)remove(u->right);
    if(u->left!=NULL)remove(u->left);
    delete u;
}
char s[maxn];
bool input_read(){
    failed = false;
    root = newnode();
    int v;
    for(;;){
    if(scanf("%s",s)!=1)return false;
    if(!strcmp(s,"()"))break;
    sscanf(&s[1],"%d",&v);
    addnode(v,strchr(s,',')+1);
    }
    return true;
}

bool bfs(vector<int>& ans){
    ans.clear();
    queue <Node* > q;
    Node* u=root;
    q.push(u);
    while(!q.empty()){
        if(u->have_valued)
        ans.push_back(u->v);
        else return false;
        q.pop();
        if(u->left!=NULL)q.push(u->left);
        if(u->right!=NULL)q.push(u->right);
        u=q.front();
    } 
    return true;
}


int main(){
    vector <int> ans;
    while(input_read()){
    if(!bfs(ans))failed=true;
    if(failed)printf("not complete
");
    else {for(int i=0;i<ans.size();i++){
            if(i!=0)printf(" ");
            printf("%d",ans[i]);
         }printf("
");
    }
    }
    return 0;
}

数组实现也差不多,用left【】right【】储存指针域,跟链表似的:

//二叉树的静态(数组)实现与层次遍历
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<vector>
#include<queue>
using namespace std;
const int maxn=256+10;
const int root=1; 

bool failed;
int cnt=1;
int left[maxn];
int right[maxn];
int value[maxn];
bool have_value[maxn];
int newnode(){int u=++cnt;left[u]=0;
    right[u]=0;have_value[u]=false;
    return u;}
bool addnode(int v,char* s){
    int n=strlen(s),t=root;
    for(int i=0;i<n;i++){
        if(s[i]=='L'){
        if(left[t]==0)left[t]=newnode();
        t=left[t];
        }
        if(s[i]=='R'){
        if(right[t]==0)right[t]=newnode();
        t=right[t];
        }
    }
   // printf("have value[%d]=%d
",t,have_value[t]);
    if(have_value[t]==true)failed=true;
    else have_value[t]=true;
    value[t]=v;
    return true;
}

void newtree(){             //相当于动态里newnode结构体拆开,因为是静态数组,无需申请内存 
    cnt=root;
    right[root]=0;
    left[root]=0;
    have_value[root]=false;
}
char s[maxn];
bool input_read(){
    failed = false;
    newtree();
    int v;
    for(;;){
    if(scanf("%s",s)!=1)return false;
    if(!strcmp(s,"()"))break;
    sscanf(&s[1],"%d",&v);
    //printf("%s
",strchr(s,',')+1);
    addnode(v,strchr(s,',')+1);
    }
    return true;
}

bool bfs(vector<int>& ans){
    ans.clear();
    queue <int> qcnt;
    int u=1;
    qcnt.push(u);
    while(!qcnt.empty()){
        u=qcnt.front();//printf("bfs-%d
",u);
        if(have_value[u]==false){return false;}
        qcnt.pop();
        ans.push_back(value[u]);
        if(left[u]!=0)qcnt.push(left[u]);
        if(right[u]!=0)qcnt.push(right[u]);
    }
    return true;
}


int main(){
    memset(have_value,false,sizeof(have_value));
    memset(left,0,sizeof(left));
    memset(right,0,sizeof(right));
    vector <int> ans;
    while(input_read()){
    if(!bfs(ans))failed=true;
    if(failed)printf("not complete
");
    else {for(int i=0;i<ans.size();i++){
            if(i!=0)printf(" ");
            printf("%d",ans[i]);
         }printf("
");
    }
    }
    return 0;
}
原文地址:https://www.cnblogs.com/-ifrush/p/10187351.html