双向链表
为什么在有时候销毁掉链表时会显示多销毁出一块空间?
定义链表的结构体类型
/* 学生信息结构体 */
typedef struct student
{
int id;
char name[32];
int score;
}DATA_STU;
/* 结点 */
typedef struct node
{
DATA_STU data;
struct node *ppre; //前驱结点的地址
struct node *pnext; //后继结点的地址
}DOU_NODE;
/* 链表标签 */
typedef struct link
{
DOU_NODE *phead;
int clen;
}DOU_LIST;
创建空链表
/* 创建控链表 */
DOU_LIST *create_linked(void)
{
DOU_LIST *plist = NULL;
plist = malloc(sizeof(DOU_LIST));
if(NULL == plist)
{
perror("fail to malloc");
return NULL;
}
plist->phead = NULL;
plist->clen = 0;
return plist;
}
添加数据
DOU_NODE *create_node(DATA_STU data)
{
DOU_NODE *pnode = NULL;
pnode = malloc(sizeof(DOU_NODE));
if (NULL == pnode)
{
perror("fail to malloc");
return NULL;
}
pnode->data = data;
pnode->ppre = NULL;
pnode->pnext = NULL;
return pnode;
}
判断是否为空链表
int is_empty_link(DOU_LIST *plist)
{
return NULL == plist->phead;
}
双向链表头插
int push_head_dou_link(DOU_LIST *plist, DOU_NODE *pnode)
{
if (NULL == plist || NULL == pnode)
{
return -1;
}
if (is_empty_link(plist))
{
plist->phead = pnode;
}
else
{
pnode->pnext = plist->phead;
plist->phead->ppre = pnode;
plist->phead = pnode;
}
plist->clen++;
return 0;
}
正向遍历
int Convenience_Linkde_List(DOU_LIST *plist)
{
DOU_NODE *ptme = NULL;
if (is_empty_link(plist))
{
return 0;
}
ptme = plist->phead;
while(ptme != NULL)
{
printf("%d %s %d\n", ptme->data.id, ptme->data.name, ptme->data.score);
ptme = ptme->pnext;
}
return 0;
}
反向遍历
int Reverse_Convenience_Linkde_List(DOU_LIST *plist)
{
DOU_NODE *ptme = NULL;
if (is_empty_link(plist))
{
return 0;
}
ptme = plist->phead;
while(ptme->pnext != NULL)
{
ptme = ptme->pnext;
}
while(ptme->ppre != NULL)
{
printf("%d %s %d\n", ptme->data.id, ptme->data.name, ptme->data.score);
ptme = ptme->ppre;
}
printf("%d %s %d\n", ptme->data.id, ptme->data.name, ptme->data.score);
return 0;
}
双向链表的尾插
int push_tail_dou_link(DOU_LIST *plist, DOU_NODE *pnode)
{
DOU_NODE *ptme = NULL;
if (NULL == plist || NULL == pnode)
{
return -1;
}
if (is_empty_link(plist))
{
plist->phead = pnode;
}
else
{
ptme = plist->phead;
while(ptme->pnext != NULL)
{
ptme = ptme->pnext;
}
ptme->pnext = pnode;
pnode->ppre = ptme;
}
plist->clen++;
return 0;
}
双向链表的头删
int Delete_Head_dou_link(DOU_LIST *plist)
{
DOU_NODE *ptme = NULL;
if (is_empty_link(plist))
{
return 0;
}
ptme = plist->phead;
if (ptme->pnext == NULL)
{
plist->phead = NULL;
free(ptme);
}
else
{
plist->phead = ptme->pnext;
ptme->pnext->ppre = NULL;
free(ptme);
}
plist->clen--;
return 0;
}
双向链表的尾删
int Delete_Tail_dou_link(DOU_LIST *plist)
{
DOU_NODE *ptme = NULL;
if (is_empty_link(plist))
{
return 0;
}
ptme = plist->phead;
if (ptme->pnext == NULL)
{
plist->phead = NULL;
free(ptme);
}
else
{
while(ptme->pnext != NULL)
{
ptme = ptme->pnext;
}
ptme->ppre->pnext = NULL;
free(ptme);
}
plist->clen--;
return 0;
}
通过名字查找
DOU_NODE *Find_Linkde_Dou_List(DOU_LIST *plist, char *name)
{
DOU_NODE *ptme = NULL;
if (is_empty_link(plist))
{
return NULL;
}
ptme = plist->phead;
while(ptme != NULL)
{
if (!strcmp(ptme->data.name, name))
{
return ptme;
}
ptme = ptme->pnext;
}
return NULL;
}
通过名字修改成绩
int Edit_Linkde_dou_List(DOU_LIST *plist,char *name, int olddata)
{
DOU_NODE *ptme = NULL;
ptme = Find_Linkde_Dou_List(plist, name);
if (ptme != NULL)
{
ptme->data.score = olddata;
return 0;
}
return -1;
}
销毁空间
int Linkde_Dou_List_Destruction(DOU_LIST *plist)
{
while(!is_empty_link(plist))
{
Delete_Head_dou_link(plist);
}
free(plist);
return 0;
}