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

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();
if(plist!=NULL)
{
if(head!=NULL)
{
plist->head = head;
plist->tail = head;
plist->size = ;
}
else
return NULL;
}
return plist;
} /*摧毁一个双向链表*/
void DestroyList(DList *plist)
{
ClearList(plist);
free(GetHead(plist));
free(plist);
} /*判断链表是否为空表*/
int IsEmpty(DList *plist)
{
if(GetSize(plist) == && GetTail(plist) == GetHead(plist))
return ;
else
return ;
}
/*将一个链表置为空表,释放原链表节点空间*/
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 = ;
Position p = GetHead(plist);
if(i>GetSize(plist)||i<)
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();
else
{ while(p->next!=NULL)
{
p = p->next;
visit(p->data);
}
}
}

test.c

 #include"dlist.h"
#include<stdio.h> void print(Item i)
{
printf("数据项为%d \n",i);
}
int main()
{
DList *plist = NULL;
PNode p = NULL; plist = InitList();
p = InsFirst(plist,MakeNode());
InsBefore(plist,p,MakeNode());
InsAfter(plist,p,MakeNode()); 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");
}

运行结果:

[walt740@localhost .Doublylinklist]$ gcc test.c dlist.c dlist.h -o test
[walt740@localhost .Doublylinklist]$ tree -L
.
├── dlist.c
├── dlist.h
├── test
├── test.c
└── \\\\\\\\\\\\
├── bin
├── obj
├── \\\\\\\\\\\\.cbp
├── \\\\\\\\\\\\.depend
└── \\\\\\\\\\\\.layout directories, files
[walt740@localhost .Doublylinklist]$ ./test
p前驱位置的值为2
p位置的值为1
p后继位置的值为3
遍历输出各节点数据项:
数据项为2
数据项为1
数据项为3
除了头节点该链表共有3个节点
删除第一个节点后重新遍历输出为:
数据项为1
数据项为3
除了头节点该链表共有2个节点
链表已被销毁
[walt740@localhost .Doublylinklist]$ ^

转自 -- http://blog.csdn.net/hopeyouknow/article/details/6716177

最新文章

  1. python向数据库插入数据时出现乱码解决方案
  2. alfresco install in linux, and integrated with tesseract ocr
  3. !带有指针的类和struct赋值的本质 - host to device
  4. b75,gtx560,I5 安装10.10.2
  5. ios 微信细节
  6. std::string和int类型的相互转换(C/C++)
  7. JavaScript不一样的语法
  8. java各种排序实现
  9. 一个i++和++i导致的严重的错误
  10. ThreadLocal就是这么简单
  11. bzoj2500幸福的道路 树形dp+单调队列
  12. 虚拟机ubuntu设置静态IP与主机、外网互ping配置流程
  13. Java 工程师成神之路 | 2019正式版
  14. 吴恩达机器学习笔记33-评估一个假设输出(Evaluating a Hypothesis Outpute)
  15. oracle大数据量更新引发的死锁问题解决方法及oracle分区和存储过程的思考
  16. release 步骤
  17. iOS使用mask切割不规则图案
  18. mysql锁文章
  19. 一个linux内核模块移植到低版本时发生的异常
  20. mysql 解决 timestamp 的2038问题

热门文章

  1. hover([over,]out)
  2. HDFS CheckPoint &amp;&amp; SavePoint
  3. abstract Factory pattern
  4. leetcode题目142.环形链表Ⅱ(中等)
  5. IntelliJ IDEA-配置文件位置
  6. 检查并解决CentOS 7 安装Tomcat是否成功
  7. k8s-helm02-----helm常用命令
  8. excel导出显示默认格子
  9. leetcode16 最接近的三数之和
  10. kotlin之包