双向链表代码实例

本文通过代码实例展示了如何实现一个双向链表,数据被封装在结构体的data指针中,确保链表与数据分离,便于管理和操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一个双向链表的实例,把数据封装在结构中的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;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值