1.双向无头链表的结构
数据域 前区指针域 后区指针域
2.双向无头链表的用法
创建链表 - 创建节点 - 头插/尾插 新节点 - 头删/尾删 新节点 - 销毁链表
1.创建链表句柄的结构体,创建双向链表的节点结构体
/*要添加的结构体内容*/
typedef struct stduent
{
int id;
char name[32];
int sore;
}DATA_TYPE;
/*节点结构体*/
typedef struct node
{
DATA_TYPE data;
struct node *ppre;
struct node *pnext;
}DOU_NODE;
/*标签结构体*/
typedef struct list
{
DOU_NODE *phead;
int clen;
}DOU_LIST;
2.创建一个空链表
/*创建链表*/
DOU_LIST *creat_doulink(void)
{
DOU_LIST *plist = malloc(sizeof(DOU_LIST));
if(NULL == plist)
{
perror("fail to malloc");
return NULL;
}
plist -> phead = NULL; //初始化
plist -> clen = 0;
return plist;
}
3.创建新的节点并且赋值
/*创建一个节点*/
DOU_NODE *creat_node(DATA_TYPE data)
{
DOU_NODE *pnode = malloc(sizeof(DOU_NODE));
if(NULL == pnode)
{
perror("fail to malloc");
return NULL;
}
pnode -> data = data;
pnode -> pnext = NULL;
pnode -> ppre = NULL;
return pnode;
}
4.头插/尾插
/*头插*/
int push_head_doulink(DOU_LIST *plist,DOU_NODE *pnode)
{
if(NULL == plist || NULL == pnode)
{
return 0;
}
if(is_empty_doulink(plist))
{
plist -> phead = pnode;
}
else
{
pnode -> pnext = plist -> phead; //第一步,将新节点的pnext指向第一个节点
plist -> phead -> ppre = pnode; //第二步,第一个节点的ppre指向新节点
plist -> phead = pnode; //第三步,将句柄的头指向新节点
}
plist -> clen++;
}
/*尾插*/
int push_tail_doulink(DOU_LIST *plist,DOU_NODE *pnode)
{
if(NULL == plist || NULL == pnode)
{
return 0;
}
if(is_empty_doulink(plist))
{
plist -> phead = pnode;
}
else
{
DOU_NODE *p = plist -> phead;
while(p -> pnext != NULL)
{
p = p -> pnext;
}
p -> pnext = pnode;
pnode -> ppre = p;
}
plist -> clen++;
return 0;
}
5.头删/尾删
/*头删*/
int delete_head_doulink(DOU_LIST *plist)
{
if(is_empty_doulink(plist))
{
return 0;
}
DOU_NODE *p = plist -> phead;
if(p -> pnext == NULL)
{
plist -> phead = NULL;
free(p);
}
else
{
plist -> phead = p -> pnext;
p -> pnext -> ppre = NULL;
free(p);
}
plist -> clen--;
}
/*尾删*/
int delete_tail_doulink(DOU_LIST *plist)
{
if(is_empty_doulink(plist))
{
return 0;;
}
DOU_NODE *p = plist -> phead;
if(p -> pnext == NULL)
{
plist -> phead = NULL;
free(p);
}
else
{
while(p -> pnext != NULL)
{
p = p -> pnext;
}
p -> ppre -> pnext = NULL;
free(p);
}
plist -> clen--;
}
6.销毁链表
/*判断链表是否为空链表*/
int is_empty_doulink(DOU_LIST *plist)
{
return NULL == plist -> phead;
}
/*销毁*/
int reverse_doulink(DOU_LIST *plist)
{
while(is_empty_doulink(plist) == 0) //判断不为空链表的时候执行
{
delete_head_doulink(plist); //重复调用头删
}
free(plist);
return 0;
}