双向链表的相关操作--C语言实现

来源:互联网 发布:淘宝图片护盾哪里 编辑:程序博客网 时间:2024/04/30 16:39
<pre name="code" class="objc">/************************************************************************//* DList.h    双向链表相关操作函数头文件*//************************************************************************/#ifndef __DList_H#define __DList_Htypedef 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()*/ //visit为函数指针void ListTraverse(DList *plist,void (*visit)(Item));/*对链表中的节点数据项进行打印*/void print(Item i);#endif/************************************************************************//* DList.c                                                                      双向链表相关操作源文件*//************************************************************************/#include "stdafx.h"#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所指结点的空间        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;    //双向链表为空,作为尾节点    pnode->next = head->next;    pnode->previous = head;    if(head->next!=NULL)        head->next->previous = pnode;    head->next = pnode;    plist->size++;    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; //若p为尾节点,则将p的前驱节点作为尾节点        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是否为头节点        p->next->previous = s;    p->next = s;    //if(p = GetTail(plist))           //old    if(p == GetTail(plist))            //new 判断位置p是否为尾节点        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)(Item)){    Position p = GetHead(plist);    if(IsEmpty(plist))        exit(0);    else    {        while(p->next!=NULL)        {            p = p->next;            visit(p->data);                    }            }}/*打印链表中节点的数据项*/void print(Item i)  {      printf("数据项为%d \n",i);  }  
int main(){    printf("双向链表操作测试\n")    DList *plist = NULL;      PNode pn = NULL;      plist = InitList();      pn = InsFirst(plist,MakeNode(1));      InsBefore(plist,pn,MakeNode(2));      InsAfter(plist,pn,MakeNode(3));      printf("p前驱位置的值为%d\n",GetItem(GetPrevious(pn)));      printf("p位置的值为%d\n",GetItem(pn));      printf("p后继位置的值为%d\n",GetItem(GetNext(pn)));    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");}


0 0
原创粉丝点击