广义表相关算法

//Header.h

#ifndef HEADER_H
#define HEADER_H

// 预定义常量和类型
// 函数结果状态代码
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define INFEASIBLE -1
#define OVERFLOW -2

typedef int Status;

#endif


/***********************************************/

//GList.h

#ifndef GLIST_H
#define GLIST_H

#include <iostream>
#include "Header.h"
using namespace std;

typedef char AtomType;
typedef enum {ATOM, LIST} ElemTag; /* ATOM==0:原子, LIST==1:子表 */
typedef struct GLNode {
    ElemTag tag; /* 公共部分,用于区分原子节点和表节点 */
    union { /* 原子节点和表节点的联合部分 */
        AtomType atom; /* atom是原子节点的值域,AtomType有用户定义 */
        struct {
            struct GLNode *hp, *tp;
        } ptr; /* ptr是表节点的指针域,ptr.hp和ptr.tp分别指向表头和表尾 */
    };
} *GList, GLNode; /* 广义表类型 */

/* 广义表的头尾链表存储的基本操作(11个) */
void InitGList(GList &L);
void CreateGList(GList &L, string S);
void DestroyGList(GList &L);
void CopyGList(GList &T, GList L);
int GListLength(GList L);
int GListDepth(GList L);
Status GListEmpty(GList L);
GList GetHead(GList L);
GList GetTail(GList L);
void InsertFirst_GL(GList &L, GList e);
void DeleteFirst_GL(GList &L, GList &e);
void Traverse_GL(GList L, void (*visit)(AtomType));
void Sever(string &sub, string &hsub);
void Visit(AtomType e);

#endif


/*****************************************************************/

//GList.cpp

/* 广义表的头尾链表存储表示 */
#include <cstdlib>
#include "GList.h"
using namespace std;

/* 创建空的广义表L */
void InitGList(GList &L)
{
    L = NULL;
}

/* 采用头尾链表存储结构,由广义表的书写形式串S创建广义表L。设emp="()" */
void CreateGList(GList &L, string S)
{
    string sub, hsub, emp("()");
    GList p, q;
    if (S == emp)
        L = NULL; /* 创建空表 */
    else {  /* S不是空串 */
        L = (GList)malloc(sizeof(GLNode));
        if (!L)
            exit(OVERFLOW);
        if (S.length() == 1) { /* S为单原子,只会出现在递归调用中 */
            L->tag = ATOM;
            L->atom = S[0]; /* 创建单原子广义表 */
            } else { /* S为表 */
                L->tag = LIST;
                p = L;
                sub =  S.substr(1, S.length() - 2); /* 脱外层括号(去掉第一个字符和最后一个字符)给串sub */
                do { /* 重复建n个子表 */
                    Sever(sub, hsub); /* 从sub中分离出表头串hsub */
                    CreateGList(p->ptr.hp, hsub);
                    q = p;
                    if(!sub.empty()) { /* 表尾不空 */
                        p = (GLNode *)malloc(sizeof(GLNode));
                        if (!p)
                            exit(OVERFLOW);
                        p->tag = LIST;
                        q->ptr.tp = p;
                    }
                } while (!sub.empty());
                q->ptr.tp = NULL;
            }
        }
}

//销毁广义表
void DestroyGList(GList &L)
{
    GList q1, q2;
    if (L) {
        if (L->tag == LIST) { // 删除表节点
            q1 = L->ptr.hp; // q1指向表头
            q2 = L->ptr.tp; // q2指向表尾
            DestroyGList(q1); //销毁表头
            DestroyGList(q2); //销毁表尾
        }
        free(L);
        L = NULL;
    }
}

// 采用头尾链表存储结构,由广义表L复制得到广义表T
void CopyGList(GList &T, GList L)
{
    if (!L) //复制空表
        T = NULL;
    else {
        T = (GList)malloc(sizeof(GLNode)); // 建表节点
        if (!T)
            exit(OVERFLOW);
        T->tag = L->tag;
        if (L->tag == ATOM)
            T->atom = L->atom; // 复制单原子
        else {
            CopyGList(T->ptr.hp, L->ptr.hp);
            CopyGList(T->ptr.tp, L->ptr.tp);
        }
    }
}

// 返回广义表的长度
int GListLength(GList L)
{
    int len = 0;
    while (L) {
        L = L->ptr.tp;
        ++len;
    }
   
    return len;
}

// 采用头尾链表存储结构,求广义表L的深度
int GListDepth(GList L)
{
    int max, dep;
    GList pp;
    if (!L)
        return 1; // 空表深度为1
    if (L->tag == ATOM)
        return 0; // 原子深度为0,只会出现在递归调用中
    for (max = 0, pp = L; pp; pp = pp->ptr.tp) {
        dep = GListDepth(pp->ptr.hp); // 递归求以pp->ptr.hp为头指针的子表深度
        if (dep > max)
            max = dep;
    }

    return max + 1; // 非空表的深度是各元素的深度的最大值加1
}

// 判定广义表是否为空
Status GListEmpty(GList L)
{
    if (!L)
        return TRUE;
    else
        return FALSE;
}

// 生成广义表L的表头元素,返回指向这个元素的指针
GList GetHead(GList L)
{
    GList h, p;
    if (!L) // 空表无表头
        return NULL;
    p = L->ptr.hp; // p指向L的表头元素
    CopyGList(h, p); // 将表头元素复制给h

    return h;
}

// 将广义表L的表尾生成为广义表,返回指向这个新广义表的指针
GList GetTail(GList L)
{
    GList t;
    if (!L) // 空表无表尾
        return NULL;
    CopyGList(t, L->ptr.tp); // 将L的表尾复制给t

    return t;
}

// 初始条件:广义表存在
//操作结果:插入元素e(也可能是子表)作为广义表L的第一个元素(表头)
void InsertFirst_GL(GList &L, GList e)
{
    GList p = (GList)malloc(sizeof(GLNode)); // 生成新节点
    if (!p)
        exit(OVERFLOW);
    p->tag = LIST; // 节点的类型是表
    p->ptr.hp = e; // 表头指向e
    p->ptr.tp = L; // 表尾指向原表
    L = p; // L指向新节点
}

// 初始条件:广义表L存在
// 操作结果:删除广义表L的第一个元素,并用e返回其值
void DeleteFirst_GL(GList &L, GList &e)
{
    GList p = L; // p指向第一个节点
    e = L->ptr.hp; // e指向L的表头
    L = L->ptr.tp; // L指向原L的表尾
    free(p); // 释放第一个节点
}

// 利用递归算法遍历广义表L
void Traverse_GL(GList L, void (*visit)(AtomType))
{
    if (L) { // 不空
        if (L->tag == ATOM) // L为单原子
            visit(L->atom);
        else { // L为广义表
            Traverse_GL(L->ptr.hp, visit); // 递归遍历L的表头
            Traverse_GL(L->ptr.tp, visit); // 递归遍历L的表头
        }
    }
}

void Visit(AtomType e)
{
    cout << e << " ";
}

void Sever(string &sub, string &hsub)
{
    int n = sub.length(), i = 0, k = 0;
    char ch;
    do {
        ch = sub[i];
        switch (ch) {
        case '(': ++k; break;
        case ')': --k; break;
        }
        ++i;
    } while (i <= n && (ch != ',' || k != 0));
    if (i <= n) {
        hsub = sub.substr(0, i - 1); //!
        sub = sub.substr(i, n - i + 1);
    } else {
        hsub = sub;
        sub.clear();
    }
}


/*****************************************************/

//main.cpp


#include "GList.h"
using namespace std;

void process(string s);

int main()
{
    string s;
    string s1("()");
    string s2("((A),((B),C),D)");
    string s3("((A,(B,(C))),(),(((((D),E)))))");
    string s4("(A,(B),(),((C)),D)");
    string s5("((),A,(B))");
    string s6("(((A,(B)),C,(D),((E)),F))");
    process(s1);
    process(s2);
    process(s3);
    process(s4);
    process(s5);
    process(s6);

    return 0;
}

void process(string s)
{
    GList L;
    CreateGList(L, s);
    int len, dep;
    len = GListLength(L);
    dep = GListDepth(L);
    cout << "len=" << len << "/tdep=" << dep << "/t";
    Traverse_GL(L, Visit);
    cout << endl;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值