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 \n",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\n",GetItem(GetPrevious(p)));  
    printf("p位置的值為%d\n",GetItem(p));  
    printf("p后繼位置的值為%d\n",GetItem(GetNext(p)));  
      
      
    printf("遍歷輸出各節點數據項:\n");  
    ListTraverse(plist,print);  
    printf("除了頭節點該鏈表共有%d個節點\n",GetSize(plist));  
    FreeNode(DelFirst(plist));  
    printf("刪除第一個節點后重新遍歷輸出為:\n");  
    ListTraverse(plist,print);  
    printf("除了頭節點該鏈表共有%d個節點\n",GetSize(plist));  
    DestroyList(plist);  
    printf("鏈表已被銷毀\n");  
}  

 

 

 

--

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM