zoukankan      html  css  js  c++  java
  • 数据结构-广义表

    广义表简称表,是线性表的推广,表中元素可以是数据元素(原子),也可以是子表。

    广义表的表头(head)是表中第一个表元素、表尾(tail)是除了表头外其它元素组成的表。

    首先要对广义表结点类GenListNode和返还值的结构类Item进行定义。它们都有一个用来标明结点类型标志域utype、一个信息域info。此外,广义表结点类还多了一个尾指针tlink指向下一个结点。

    utype为0时为广义表专用的附加头结点,info存放引用计数ref

    utype为1时为原子结点、info存放数据值value

    utype为2时为子表结点,info存放指向子表表头的指针hlink

    这种存储表示中,广义表中的所有表,无论是哪一层的子表,都带有一个附加头结点,空表也不例外

    所有位于同一层的表元素,在其存储表示中也在同一层

    最高一层的表结点个数(除附加头结点外)即为表的长度

    #include <iostream>
    #include <assert.h>
    #include <stdlib.h>
    using namespace std;
    
    template <class T>
    struct Items{     //返回值的类结构定义
        int utype;   //标志域
        union{
            int ref;    //utype=0,存放引用计数
            T value;     //utype=1,存放数值
            GenListNode<T> *hlink;   //utype=2.存放指向子表的指针
        } info;
        Items():utype(0),info.ref(0){} //构造函数
        Items(Items<T>& RL){utype=RL.utype;info=RL.info;} //复制构造函数
    }
    
    template <class T>
    struct GenListNode{   //广义表结点类定义
    public:
        GenListNode():utype(0),tlink(NULL),info.ref(0){}
        GenListNode(GenListNode<T>& RL){utype=RL.utype;tlink=Rl.tlink;info=RL.info;}
    private:
        int utype;
        GenListNode<T> *tlink;    //比返回值的类结构多了一个tlink指针
        union{
            int ref;
            T value;
            GenListNode<T> *tlink;
        } info;
    }
    
    template <class T>
    class Genlist{
    public:
        Genlist();
        ~Genlist();
        bool Head(Items& x);
        bool Tail(Genlist<T>& It);
        GenListNode<T> *First();
        GenListNode<T> *Next(GenListNode<T> *elem);
        void Copy(const Genlist<T>& R);
        int Length();
        int depth();
    friend istream& operator>>(istream& in,Genlist<T>& L);
    private:
        GenListNode<T> *first;   //广义表头指针
        GenListNode<T> *Copy(GenListNode<T> *ls);
        int Length(GenListNode<T> *ls);
        int depth(GenListNode<T> *ls);
        bool equal(GenListNode<T> *s,GenListNode<T> *t);  //判断s和t为表头的两个表是否相等
        void Remove(GenListNode<T> *ls);
        void Createlist(istream& in,GenListNode<T> *&ls);
    }
    
    
    template <class T>
    Genlist<T>::Genlist(){    //构造函数
        first=new GenlistNode;
        assert(first!=NULL);
    }
    
    //Head方法返回bool值,通过引用变量x返回是广义表第一个元素(Item类型的对象);
    template <class T>
    bool Genlist<T>::Head(Items<T>& x){
        //若广义表非空,则通过x返回其第一个元素的值,否则函数没有意义
        if(first->tlink==NULL) return false;
        else{
            x.utype=first->tlink->utype;
            x.info=first->tlink->info;
            return true;
        }
    }
    
    template <class T>
    bool Genlist<T>::Tail(Genlist<T>& It){
        //若广义表非空,则通过It返回广义表除表头元素以外其他元素组成的表,否则函数没有意义
        if(first->tlink==NULL) return false;
        else{
            It.first->utype=0;
            It.first->info.ref=0;
            It.first->tlink=Copy(first->tlink->tlink);
            return true;
        }
    }
    //First方法返回的是指向广义表第一个元素(GenlistNode类型的对象)的指针
    template <class T>
    GenlistNode<T> *Genlist<T>::First(){
        if(first->tlink==NULL)return NULL;
        else return first->tlink;
    }
    template <class T>
    GenlistNode<T> *Genlist<T>::Next(GenlistNode<T> *elem){    //返回表元素elem的直接后继元素
        if(elem->tlink==NULL) return NULL;
        else return elem->tlink;
    }

     广义表的遍历可以用如下方法:

    template <class T>
    struct Items {
        int mark;
        int utype;
        union{
            char *LName;   //附加头结点的info域改为了表名
            T value;
            GenListNode<T> *hlink;
        }info;
        Items():mark(0),utype(0),info.LName(''){}
        Items(Items<T>& RL){mark=Rl.mark;utype=RL.utypr;info=RL.info;}
    }
    
    template <class T>
    struct GenListNode {
    public:
        GenListNode():mark(0),utype(0),tlink(NULL),info.LName(''){}
        GenListNode(GenListNode<T>& RL){mark=RL.mark; utype=RL.utype; tlink=RL.tlink; info=RL.info;}
        int getMark(GenListNode<T> *elem){return elem->mark;}
        int getType(GenListNode<T> *elem){return elem->utype;}
        int getListName(GenListNode<T> *elem){return elem->info.LName;}
        T getValue(GenListNode<T>* elem){return elem->info.value;}
        GenListNode* gettlink(GenListNode<T>* elem){return elem->tlink;}
        GenListNode* gethlink(GenListNode<T>* elem){return elem->info.hlink;}
    private:
        int mark;
        int utype;
        GenListNode<T> *tlink;
        union{
            char *LName;
            T value;
            GenListNode<T> *hlink;
        }info;
    }
    
    template GenList{
    public:
        GenList();
        ~GenList(){Remove(first);}
        bool Head(Items& x);
        bool Tail(GenList<T> &lt);
        GenListNode<T> *First(){return first;}
        GenListNode<T> *Next(GenListNode<T> *elem){return elem->tlink;}
        void Traverse(); //非递归遍历
    private:
        GenListNode<T> *first;
        void Traverse(GenListNode<T> *ls); //递归遍历
    }
    
    template <class T>
    void GenList::Traverse(){
        Stack<GenListNode<T>*> st;
        GenListNode<T> *ls=first;
        while (ls!=NULL) {
            ls->mark=1;
            if (ls->utype==2){  //子表结点
                if (ls->info.hlink->mark==0){
                    st.Push(ls->tlink;) //暂时先把子表结点的右结点入栈
                    ls=ls->hlink;
                }
                else { //子表已经遍历过
                    cout<<ls->info.hlink->info.LName;
                    if(ls->tlink!=NULL){
                        cout<<',';
                        ls=ls->tlink;
                    }
                }
            }
            else {
                if (ls->utype==0) cout<<ls->info.LName<<'(';  //表头结点
                else if (ls->utype==1){ //原子结点
                    cout<<ls->info.value;
                    if(ls->tlink!=NULL) cout<<',';
                }
                if(ls->tlink==NULL){
                    cout<<')';
                    if(!st.isEmpty()){
                        st.Pop(ls);
                        if(ls!=NULL) cout<<',';
                        else cout<<')';
                    }
                }
                else ls=ls->tlink;
            }
        }
    }
    
    template <class T>
    void GenList::Traverse(GenListNode<T> *ls){
        if(ls!=NULL){
            ls->mark=1;
            if (ls->utype==0) cout<<ls->info.LName<<'(';  //表头结点
            else if (ls->utype==1) {  //原子结点
                cout<<ls->info.value;
                if (ls->tlink!=NULL) cout<<',';
            }
            else if (ls->utype==2) { //子表结点
                if (ls->info.hlink->mark==0) Traverse(ls->info.hlink);
                else cout<<ls->info.hlink->info.LName; //子表已经遍历过
                if (ls->tlink!=NULL) cout<<',';
            }
            Traverse(ls->tlink);
        }
        else cout<<')';
    }
  • 相关阅读:
    uva 489 Hangman Judge(水题)
    中国海洋大学第四届朗讯杯高级组 Cash Cow(模拟)
    中国海洋大学第四届朗讯杯高级组 A 2718 Rocky(模拟)
    poj 1039 Pipe(叉乘。。。)
    CodeForces 135 B. Rectangle and Square(判断正方形和 矩形)
    poj 1265 Area( pick 定理 )
    poj 2031 Building a Space Station(prime )
    hdu 4502 吉哥系列故事——临时工计划(dp)
    拉格朗日插值
    [USACO18DEC]The Cow Gathering P
  • 原文地址:https://www.cnblogs.com/yangyuliufeng/p/9479831.html
Copyright © 2011-2022 走看看