双向循环链表模板

来源:互联网 发布:养出通透的皮肤知乎 编辑:程序博客网 时间:2024/06/01 23:38
#include <stdio.h>#include <malloc.h>#include <stdlib.h>#include "iostream"using namespace std;#define MAXNUM 0x7fffffff#define MAXSCORE 100000typedef struct LNode {    int num;//学号     char name[20];//姓名     double score;//成绩     struct LNode *prior; //前向指针     struct LNode *next;  //后项指针} LNode, *LinkList;// 2、测链表长度int ListLength_L(LinkList L){    int i;    LinkList p = L->next;    for(i=0,p=L;p->next!=L;p=p->next,i++);//空循环,只计数 ;i能从1开始吗?     return i;} // 3、销毁链表void DestroyList_L(LinkList &L){    LinkList p = L->prior->prior;    for(L->prior==NULL;p;p=p->prior)//从后向前逐个销毁         free(p->next);    free(L);}// 4、返回第pos个元素的地址LinkList ListGetElem(LinkList L, int pos){    LinkList e = NULL; //定义结点指针    int len = ListLength_L(L);    if(pos<0 || pos>len)return 0;  //位置不合法 ,思考为什么0也合法?     e = L;     for(int i=0;i<pos;i++,e=e->next);  //空循环体,只是把e定位到pos-1     return e;}// 1、创建一个空的双向循环链表 int InitList_L(LinkList &L){    if(L)DestroyList_L(L);//如果链表已存在,先销毁     L = (LinkList) malloc (sizeof (LNode));    if (!L) return 1; // 存储分配失败    L->num = MAXNUM; L->score = MAXSCORE;//表头空结点赋特殊值     memset(L->name,0,sizeof(L->name));    L->prior = L;  // 双向循环链表只有表头空节点时,前向和后向     L->next = L;   // 指针都是指向自己的     return 0;}// 5、顺序输出链表void PrintList_L(LinkList L){    LinkList p = L->next;    for(;p!=L;p=p->next)        cout << p->num << ' ' << p->name << ' ' << p->score << endl;}// 6、在链表中t指向的元素之后插入元素int ListInsert_L(LinkList t, LNode e){    if(!t)return 1;//获取地址失败,返回     LinkList p = (LinkList) malloc (sizeof (LNode));    if (!p) return 1; // 存储分配失败    *p = e;             //结构体是可以直接赋值的     p->next = t->next;  t->next = p;  //后向指针链接修改     p->next->prior = p; p->prior = t; //前向指针链接修改    return 0;}// 7、构造带数据的链表int CreateList_L(LinkList &L){    if(L)DestroyList_L(L);//如果链表已存在,先销毁    InitList_L(L);      //初始化链表     int i,n;    cin >> n;    while(n--)    {        LinkList p = (LinkList) malloc (sizeof (LNode));        if (!p) return 1; // 存储分配失败        cin >> p->num >> p->name >> p->score;        LinkList t = L->prior;        p->next = t->next;  t->next = p;  //后向指针链接修改         p->next->prior = p; p->prior = t; //前向指针链接修改    }}// 8、删除p指向的元素int ListDelete_L(LinkList p){    if (p->num==MAXNUM || !p) return 1;//判定删除位置是否合法,表头能删吗?     p->prior->next = p->next;    //后向指针链接修改    p->next->prior = p->prior;  //前向指针链接修改    free(p);            //销毁该元素     return 0;} // 9、学号相等判定函数int CmpNum(LinkList pa, LinkList pb){    return pa->num == pb->num;}// 10、查找并返回地址,未找到返回表头空结点地址,利用外部函数判定LinkList LocateElem_L(LinkList L, LNode e, int (*cmp)(LinkList,LinkList)){    LinkList p=L->next;  //p是查找指针     for(;p!=L;p=p->next)        if(cmp(p,&e))break;//循环查找,找到推出循环     return p;               //返回找到元素的地址,或表头地址 }// 11、成绩小于判定函数int cmp(LinkList pa, LinkList pb){    return pa->score < pb->score;}// 12、有序合并链表int Merg_L(LinkList La, LinkList Lb, LinkList &Lc){    if(Lc)DestroyList_L(Lc);            //如果Lc不为空,销毁     if(InitList_L(Lc))return 1;         //初始化Lc     LinkList pa,pb,pc,t;                //定义指向三个链表元素的指针     LNode e;                            //定义一个结点变量,用于保存待插入学生数据     for(pa=La->next;pa!=La;pa=pa->next)     {        e = *pa;                        //待插入数据赋给e         t = LocateElem_L(Lc,e,cmp)->prior; //查找e插入的位置,找到插入点前驱结点地址         ListInsert_L(t,e);              //插入e    }    for(pb=Lb->next;pb!=Lb;pb=pb->next)    {        e = *pb;        t = LocateElem_L(Lc,e,cmp)->prior;        ListInsert_L(t,e);    }}int main(){    LNode e;    LinkList l[4]={0};    LinkList t;    freopen("twlist.in","r",stdin);    freopen("twlist.out","w",stdout);    int n;    cin >> n;    while(n--)    {        int x,y,pos;        cin >> x;        switch(x)        {            case 1: cin >> y;                    PrintList_L(l[y]);                    break;            case 2: InitList_L(l[1]);                    break;            case 3: cin >> pos >> e.num >> e.name >> e.score;                    ListInsert_L(ListGetElem(l[1],pos-1),e);                    break;            case 4: CreateList_L(l[2]);                    break;            case 5: cin >> pos;                    ListDelete_L(ListGetElem(l[1],pos));                    break;            case 6: cin >> e.num;                    t = LocateElem_L(l[1],e,CmpNum);                    ListDelete_L(t);                    break;            case 7: Merg_L(l[1],l[2],l[3]);                    break;        }    }    return 0;}
0 0
原创粉丝点击