zoukankan      html  css  js  c++  java
  • C语言一个双向链表的实现

    --

    DList.c

    #include"DList.h"  
    #include<malloc.h>  
    #include<stdlib.h>  
    /*分配值为i的节点,并返回节点地址*/  
    Position MakeNode(Item i)  
    {  
        PNode p = NULL;   
        p = (PNode)malloc(sizeof(Node));  
        if(p!=NULL)  
        {  
            p->data = i;  
            p->previous = NULL;  
            p->next = NULL;  
        }     
        return p;  
    }  
    /*释放p所指的节点*/  
    void FreeNode(PNode p)  
    {  
         free(p);  
    }  
    /*构造一个空的双向链表*/  
    DList * InitList()  
    {  
        DList *plist = (DList *)malloc(sizeof(DList));  
        PNode head = MakeNode(0);   
        if(plist!=NULL)  
        {  
            if(head!=NULL)  
            {  
                plist->head = head;  
                plist->tail = head;  
                plist->size = 0;  
            }  
            else  
                return NULL;  
        }  
        return plist;  
    }  
      
    /*摧毁一个双向链表*/  
    void DestroyList(DList *plist)  
    {  
        ClearList(plist);  
        free(GetHead(plist));  
        free(plist);  
    }  
      
    /*判断链表是否为空表*/  
    int IsEmpty(DList *plist)  
    {  
        if(GetSize(plist)==0&&GetTail(plist)==GetHead(plist))  
            return 1;  
        else  
            return 0;  
    }  
    /*将一个链表置为空表,释放原链表节点空间*/  
    void ClearList(DList *plist)  
    {  
        PNode temp,p;  
        p = GetTail(plist);  
        while(!IsEmpty(plist))  
        {     
            temp = GetPrevious(p);  
            FreeNode(p);  
            p = temp;  
            plist->tail = temp;  
            plist->size--;  
        }  
    }  
      
    /*返回头节点地址*/  
    Position GetHead(DList *plist)  
    {  
        return plist->head;  
    }  
      
    /*返回尾节点地址*/  
    Position GetTail(DList *plist)  
    {  
        return plist->tail;  
    }  
      
    /*返回链表大小*/  
    int GetSize(DList *plist)  
    {  
        return plist->size;  
    }  
      
    /*返回p的直接后继位置*/  
    Position GetNext(Position p)  
    {  
        return p->next;  
    }  
      
    /*返回p的直接前驱位置*/  
    Position GetPrevious(Position p)  
    {  
        return p->previous;  
    }  
      
    /*将pnode所指节点插入第一个节点之前*/  
    PNode InsFirst(DList *plist,PNode pnode)  
    {  
        Position head = GetHead(plist);  
      
        if(IsEmpty(plist))  
            plist->tail = pnode;  
        plist->size++;  
      
        pnode->next = head->next;  
        pnode->previous = head;  
      
        if(head->next!=NULL)  
            head->next->previous = pnode;  
        head->next = pnode;  
          
        return pnode;   
    }  
      
    /*将链表第一个节点删除,返回该节点的地址*/  
    PNode DelFirst(DList *plist)  
    {  
        Position head = GetHead(plist);  
        Position p=head->next;  
        if(p!=NULL)  
        {  
            if(p==GetTail(plist))  
                plist->tail = p->previous;  
            head->next = p->next;  
            head->next->previous = head;  
            plist->size--;  
              
        }     
        return p;  
    }  
      
    /*获得节点的数据项*/  
    Item GetItem(Position p)  
    {  
        return p->data;  
    }  
      
    /*设置节点的数据项*/  
    void SetItem(Position p,Item i)  
    {  
        p->data = i;  
    }  
      
    /*删除链表中的尾节点并返回地址,改变链表的尾指针指向新的尾节点*/  
    PNode Remove(DList *plist)  
    {  
        Position p=NULL;  
        if(IsEmpty(plist))  
            return NULL;  
        else  
        {  
            p = GetTail(plist);  
            p->previous->next = p->next;  
            plist->tail = p->previous;  
            plist->size--;  
            return p;  
        }  
    }  
    /*在链表中p位置之前插入新节点s*/  
    PNode InsBefore(DList *plist,Position p,PNode s)  
    {  
        s->previous = p->previous;  
        s->next = p;  
        p->previous->next = s;      
        p->previous = s;  
      
        plist->size++;  
        return s;  
    }  
    /*在链表中p位置之后插入新节点s*/  
    PNode InsAfter(DList *plist,Position p,PNode s)  
    {  
        s->next = p->next;  
        s->previous = p;  
          
        if(p->next != NULL)  
            p->next->previous = s;  
        p->next = s;  
          
        if(p = GetTail(plist))  
            plist->tail = s;  
          
        plist->size++;  
        return s;  
    }  
      
    /*返回在链表中第i个节点的位置*/  
    PNode LocatePos(DList *plist,int i)  
    {  
        int cnt = 0;  
        Position p = GetHead(plist);  
        if(i>GetSize(plist)||i<1)  
            return NULL;  
      
        while(++cnt<=i)  
        {  
            p=p->next;  
        }  
      
        return p;  
    }  
      
    /*依次对链表中每个元素调用函数visit()*/  
    void ListTraverse(DList *plist,void (*visit)())  
    {  
        Position p = GetHead(plist);  
        if(IsEmpty(plist))  
            exit(0);  
        else  
        {  
              
            while(p->next!=NULL)  
            {  
                p = p->next;  
                visit(p->data);            
            }         
        }  
    }  

    DList.h

    #ifndef DList_H  
    #define DList_H  
    typedef  int Item;  
    typedef struct Node * PNode;  
    typedef PNode Position;  
    /*定义节点类型*/  
    typedef struct Node  
    {  
        Item data;      /*数据域*/  
        PNode previous; /*指向前驱*/  
        PNode next;     /*指向后继*/  
    }Node;  
    /*定义链表类型*/  
    typedef struct  
    {  
        PNode head;     /*指向头节点*/  
        PNode tail;     /*指向尾节点*/  
        int size;  
    }DList;  
      
    /*分配值为i的节点,并返回节点地址*/  
    Position MakeNode(Item i);  
      
    /*释放p所指的节点*/  
    void FreeNode(PNode p);  
      
    /*构造一个空的双向链表*/  
    DList* InitList();  
      
    /*摧毁一个双向链表*/  
    void DestroyList(DList *plist);  
      
    /*将一个链表置为空表,释放原链表节点空间*/  
    void ClearList(DList *plist);  
      
    /*返回头节点地址*/  
    Position GetHead(DList *plist);  
      
    /*返回尾节点地址*/  
    Position GetTail(DList *plist);  
      
    /*返回链表大小*/  
    int GetSize(DList *plist);  
      
    /*返回p的直接后继位置*/  
    Position GetNext(Position p);  
      
    /*返回p的直接前驱位置*/  
    Position GetPrevious(Position p);  
      
    /*将pnode所指节点插入第一个节点之前*/  
    PNode InsFirst(DList *plist,PNode pnode);  
      
    /*将链表第一个节点删除并返回其地址*/  
    PNode DelFirst(DList *plist);  
      
    /*获得节点的数据项*/  
    Item GetItem(Position p);  
      
    /*设置节点的数据项*/  
    void SetItem(Position p,Item i);  
      
    /*删除链表中的尾节点并返回其地址,改变链表的尾指针指向新的尾节点*/  
    PNode Remove(DList *plist);  
      
    /*在链表中p位置之前插入新节点S*/  
    PNode InsBefore(DList *plist,Position p,PNode s);  
      
    /*在链表中p位置之后插入新节点s*/  
    PNode InsAfter(DList *plist,Position p,PNode s);  
      
    /*返回在链表中第i个节点的位置*/  
    PNode LocatePos(DList *plist,int i);  
      
    /*依次对链表中每个元素调用函数visit()*/  
    void ListTraverse(DList *plist,void (*visit)());  
    #endif 

    main.c

    #include"DList.h"  
    #include<stdio.h>  
    void print(Item i)  
    {  
        printf("数据项为%d 
    ",i);  
    }  
    main()  
    {  
        DList *plist = NULL;  
        PNode p = NULL;  
          
        plist = InitList();  
        p = InsFirst(plist,MakeNode(1));  
        InsBefore(plist,p,MakeNode(2));  
        InsAfter(plist,p,MakeNode(3));  
      
        printf("p前驱位置的值为%d
    ",GetItem(GetPrevious(p)));  
        printf("p位置的值为%d
    ",GetItem(p));  
        printf("p后继位置的值为%d
    ",GetItem(GetNext(p)));  
          
          
        printf("遍历输出各节点数据项:
    ");  
        ListTraverse(plist,print);  
        printf("除了头节点该链表共有%d个节点
    ",GetSize(plist));  
        FreeNode(DelFirst(plist));  
        printf("删除第一个节点后重新遍历输出为:
    ");  
        ListTraverse(plist,print);  
        printf("除了头节点该链表共有%d个节点
    ",GetSize(plist));  
        DestroyList(plist);  
        printf("链表已被销毁
    ");  
    }  

    --

  • 相关阅读:
    关于求 p_i != i and p_i != i+1 的方案数的思考过程
    poj 3041 Asteroids 二分图最小覆盖点
    poj 1325 Machine Schedule 最小顶点覆盖
    poj 1011 Sticks 减枝搜索
    poj 1469 COURSES 最大匹配
    zoj 1516 Uncle Tom's Inherited Land 最大独立边集合(最大匹配)
    Path Cover (路径覆盖)
    hdu 3530 SubSequence TwoPoint单调队列维护最值
    zoj 1654 Place the Rebots 最大独立集转换成二分图最大独立边(最大匹配)
    poj 1466 Girls and Boys 二分图最大独立子集
  • 原文地址:https://www.cnblogs.com/Ph-one/p/6764951.html
Copyright © 2011-2022 走看看