一个双向链表的实例,把数据封装在结构中的data指针中,是的链表和数据各自独立。
.h file
#ifndef ListOper_H
#define ListOper_H
#include<malloc.h>
#include<stdlib.h>
//--------------data结构体-------------------------
typedef struct struct_data {
int id;
char name[20];
char src[80];
char dst[80];
}S_XXX;
//--------------data结构体-------------------------
/*数据置零*/
void ZeroXXX(S_XXX *pData);
/*数据拷贝,每次使用前调用ZeroCDR函数,确保字符串以nul结束*/
void CopyXXX(S_XXX *pData, S_XXX *pSrc);
/*构造cdr数据:pData为NULL时,各成员初始化为空;非NULL时,拷贝pData。*/
S_XXX * MakeXXX(S_XXX *pData);
//--------------List结构体-------------------------
typedef void * Item;
typedef struct Node * PNode;
/*定义节点类型*/
struct Node
{
Item data; //data; /*数据域*/
PNode previous; /*指向前驱*/
PNode next; /*指向后继*/
};
/*定义链表类型*/
typedef struct
{
PNode head; /*指向头节点*/
PNode tail; /*指向尾节点*/
int size; /*指向链表节点个数,不包含head节点*/
}DList;
//--------------List结构体-------------------------
/******************************Oper Start*****************************/
/*分配值为i的节点,并返回节点地址*/
PNode MakeNode(Item data, int flag);
/*释放p所指的节点*/
void FreeNode(PNode p);
/*构造一个空的list双向链表*/
DList* InitList(int flag);
/*摧毁一个双向链表*/
void DestroyList(DList *plist);
/*将一个链表置为空表,释放原链表节点空间*/
void ClearList(DList *plist);
/*返回头节点地址*/
PNode GetHead(DList *plist);
/*返回尾节点地址*/
PNode GetTail(DList *plist);
/*返回链表大小*/
int GetSize(DList *plist);
/*返回p的直接后继位置*/
PNode GetNext(DList *plist, PNode p);
/*返回p的直接前驱位置,前驱为head则指向tail*/
PNode GetPrevious(DList *plist, PNode p);
/*返回p的直接前驱位置*/
PNode GetPrevious2(DList *plist, PNode p);
/*将pnode所指节点插入第一个节点之前*/
PNode InsFirst(DList *plist,PNode pnode);
/*将链表第一个节点删除并返回其地址*/
PNode DelFirst(DList *plist);
/*获得节点的数据项*/
Item GetItem(PNode p);
/*设置节点的数据项*/
void SetItem(PNode p, Item data);
/*删除链表中的尾节点并返回其地址,改变链表的尾指针指向新的尾节点*/
PNode DelTail(DList *plist);
/*删除p节点,并返回p节点地址*/
PNode DelItem(DList *plist, PNode p, int *size);
/*在链表中p位置之前插入新节点S*/
PNode InsBefore(DList *plist,PNode p,PNode s);
/*在链表中p位置之后插入新节点s*/
PNode InsAfter(DList *plist,PNode p,PNode s);
/*返回在链表中第i个节点的位置*/
PNode LocatePos(DList *plist,int i);
/*依次对链表中每个元素调用函数visit()*/
void ListTraverse(DList *plist,void (*visit)());
/******************************Oper End*****************************/
#endif
.c file:
#include"ListOper.h"
/*S_XXX数据置零*/
void ZeroXXX(S_XXX *pData)
{
pData->id = 0;
memset(pData->name, '\0', sizeof(char)*20);
memset(pData->src, '\0', sizeof(char)*80);
memset(pData->dst, '\0', sizeof(char)*80);
}
/*S_XXX数据拷贝确保字符串以nul结束*/
void CopyXXX(S_XXX *pData, S_XXX *pSrc)
{
pData->id = pSrc->acctid;
strcpy(pData->name, pSrc->name);
strcpy(pData->src, pSrc->src);
strcpy(pData->dst, pSrc->dst);
}
/*构造S_XXX数据:pData为NULL时,各成员初始化为空;非NULL时,拷贝pData。*/
S_XXX * MakeXXX(S_XXX *pData)
{
S_XXX *p = NULL;
p = (S_XXX *)malloc(sizeof(struct S_XXX));
if(p!=NULL){
if(pData == NULL)
ZeroXXX(p);
else{
ZeroXXX(p);
CopyXXX(p, pData);
}
}
return pCdr;
}
/*分配值为i的节点,并返回节点地址*/
PNode MakeNode(Item data, int flag)
{
PNode p = NULL;
p = (PNode)malloc(sizeof(struct Node));
if(p!=NULL)
{
if(1 == flag)
p->data = MakeXXX(data);
else
;//p->data = MakeXXX(data);
p->previous = NULL;
p->next = NULL;
}
return p;
}
/*释放p所指的节点*/
void FreeNode(PNode p)
{
free(p);
}
/*构造一个空的calllog list双向链表; 0,conference; 1,sdr*/
DList * InitList(int flag)
{
DList *plist = (DList *)malloc(sizeof(DList));
PNode head = MakeNode(NULL, flag);
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);
plist = NULL;
}
/*判断链表是否为空表*/
int IsEmpty(DList *plist)
{
if(GetSize(plist)==0&&GetTail(plist)==GetHead(plist))
return 1;
else
return 0;
}
/*返回p的直接前驱位置*/
PNode GetPreviousOnly(DList *plist, PNode p)
{
return p->previous;
}
/*将一个链表置为空表,释放原链表节点空间*/
void ClearList(DList *plist)
{
PNode temp,p;
p = GetTail(plist);
while(!IsEmpty(plist))
{
temp = GetPreviousOnly(plist, p);
//FreeCDR(p->data);
free(p->data);
FreeNode(p);
p = temp;
plist->tail = temp;
plist->size--;
}
}
/*返回头节点地址*/
PNode GetHead(DList *plist)
{
return plist->head;
}
/*返回尾节点地址*/
PNode GetTail(DList *plist)
{
return plist->tail;
}
/*返回链表大小*/
int GetSize(DList *plist)
{
return plist->size;
}
/*返回p的直接后继位置*/
PNode GetNext(DList *plist, PNode p)
{
//p is tail
if(p->next == NULL)
p = GetHead(plist);
return p->next;
}
/*返回p的直接前驱位置*/
PNode GetPrevious(DList *plist, PNode p)
{
//p is head
if(p->previous == GetHead(plist)){
return GetTail(plist);
}
else
return p->previous;
}
/*将pnode所指节点插入第一个节点之前*/
PNode InsFirst(DList *plist,PNode pnode)
{
PNode 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)
{
PNode head = GetHead(plist);
PNode 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;
}
/*删除链表中的尾节点并返回地址,改变链表的尾指针指向新的尾节点*/
PNode DelTail(DList *plist)
{
PNode p=NULL;
if(IsEmpty(plist))
return NULL;
else
{
p = GetTail(plist);
p->previous->next = p->next;
plist->tail = p->previous;
plist->size--;
return p;
}
}
/*将链表第一个节点删除,返回该节点的地址*/
PNode DelItem(DList *plist, PNode p, int *size)
{
if(p!=NULL)
{
if(p == GetTail(plist)){
p = DelTail(plist);
}
else if(p == GetHead(plist)){
p = DelFirst(plist);
}
else{
PNode pre = p->previous;
pre->next = p->next;
p->next->previous = pre;
plist->size--;
}
}
else{
return NULL;
}
*size = plist->size;
return p;
}
/*获得节点的数据项*/
Item GetItem(PNode p)
{
return p->data;
}
/*设置节点的数据项*/
void SetItem(PNode p, Item data)
{
CopyCDR(p->data, data);
}
/*在链表中p位置之前插入新节点s*/
PNode InsBefore(DList *plist,PNode 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,PNode 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;
PNode 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)())
{
PNode p = GetHead(plist);
if(IsEmpty(plist))
exit(0);
else
{
while(p->next!=NULL)
{
p = p->next;
visit(p->data);
}
}
}
test file:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "ListOper.h"
DList *plist;
static int gs_LogNum;
DList* AssembleCallLogList(int *LogNum)
{
char line[1024];
int count = 0;
int i;
S_XXX tmpData;
DList *plist = InitList(1);
while(fieldCount--) {
ZeroCDR(&tmpData);
InsAfter(plist,plist->tail,MakeNode(&tmpData, 1));
}
*LogNum = count;
return plist;
}
int main(int argc, char *argv[])
{
PNode p;
int i;
plist = AssembleCallLogList(&gs_LogNum);
if((plist == NULL) || (gs_LogNum == 0)){
;
}
pCur = LocatePos(plist, 1);
printf("S_XXX name is:%s.",((S_XXX *)(pCur->data))->name));
DestroyList(plist);
return 0;
}