数据结构之广义表(头尾链表存储)基本操作

来源:互联网 发布:自学计算机游戏编程 编辑:程序博客网 时间:2024/05/21 05:43

#include<iostream>using namespace std;typedef char AtomType;typedef enum{ ATOM, LIST }ElemTag;typedef struct GLNode{ElemTag tag;union{AtomType atom;struct{GLNode *pHead, *pTail;}table;};}GLNode, *GList;void InitGList(GList &L){L = NULL;}//创建空的广义表void DestroyGList(GList &L){GList p1, p2;if (L){if (L->tag == ATOM)//原子结点{delete L;L = NULL;}else//表结点{p1 = L->table.pHead;//保存表头指针p2 = L->table.pTail;//保存表尾指针delete L;//处理表结点L = NULL;DestroyGList(p1);//递归销毁表头DestroyGList(p2);//递归销毁表尾}}}void CopyGList(GList &T, GList L){if (!L)T = NULL;else{T = new GLNode;T->tag = L->tag;if (L->tag == ATOM)//递归时会用到T->atom = L->atom;else//表结点{CopyGList(T->table.pHead, L->table.pTail);CopyGList(T->table.pTail, L->table.pTail);}}}int GListLength(GList L){// 返回广义表的长度,即元素个数int len = 0;if (!L)return 0;if (L->tag == ATOM)//L->Tag不可能是ATOM(非递归操作)(在这里只是为了结构的美观)return 1;while (L){++len;L = L->table.pTail;}return len;}int GListDepth(GList L){int max = 0, dep;GList p = L;if (!L)return 1;else{if (L->tag == ATOM)//递归时才用到return 0;else{while (p)//对每个元素求dep{dep = GListDepth(p->table.pHead);//每次循环求得一个子表的深度if (dep > max)max = dep;p = p->table.pTail;//指向新表尾}return max + 1;}}}int GListDepth_(GList L){int deph, dept;if (!L)return 1;else if (L->tag = ATOM)return 0;deph = GListDepth(L->table.pHead) + 1;dept = GListDepth(L->table.pTail);return deph > dept ? deph : dept;}//未校验bool GlistEmpty(GList L){if (!L)return true;elsereturn false;}GList GetHead(GList L){ // 取广义表L的头GList h, p;if (!L){cout << "空表无表头!" << endl;return NULL;}else{//如果表中第一个元素为原子,如此设置方便操作,注意和GetTail()的区别p = L->table.pTail;L->table.pTail = NULL;//断开表头与表尾联系CopyGList(h, L);//复制表头,此时L指向的是一个独立的表头L->table.pTail = p;//接上表头与表尾联系return h;}}GList GetTail(GList L){GList t;if (!L){cout << "空表无表尾!" << endl;return NULL;}else//表尾肯定是广义表{CopyGList(t, L->table.pTail);return t;}}void InsertHead(GList &L, GList pe){//广义表已存在为前提// 操作结果: 插入元素e作为广义表L的第一元素(表头,也可能是子表)GList p = new GLNode;p->tag = LIST;p->table.pHead = pe;p->table.pTail = L;L = p;}void DeleteHead(GList &L, GList &pe){// 初始条件: 广义表L存在// 操作结果: 删除广义表L的第一元素,并用e返回其值GList p;pe = L->table.pHead;p = L;L = L->table.pTail;if (p->table.pHead->tag == LIST){//如果表头指向的是原子的话,我们最好保留表头结点,这样是为了把它当作一个广义表更好的操作//如果表头指向的是广义表的话,我们毫无理由的要删除该表头结点delete p;p = NULL;}}void DeleteElem(GList &L, AtomType e){GList h = NULL, p = NULL;if (L){h = L->table.pHead;if (h)//处理表头{if (h->tag == ATOM &&h->atom == e)//删除该子表{//处理表头指针指向的原子,且必须满足值相等才处理,否则不处理p = L; L = L->table.pTail;delete h;//删除原子结点,注意顺序delete p;//删除表结点,注意顺序DeleteElem(L, e);//递归处理更新后的广义表}else//处理表头指针指向的广义表{if (h->tag == LIST)DeleteElem(L, e);DeleteElem(L->table.pTail, e);}}else//递归处理表尾指针指向的广义表DeleteElem(L->table.pTail, e);}}//有待校验void VisitAtom(AtomType atom){cout << atom << endl;}void GListPrint(GList L){ // 利用递归算法遍历广义表Lif (L)//空表不处理{if (L->tag == ATOM)// L为单原子,递归时才用到VisitAtom(L->atom);else //L为广义表{//第一次肯定执行elseGListPrint(L->table.pHead);GListPrint(L->table.pTail);}}}//函数校验要借助于串和串操作函数实现

0 0