双向链表:
节点=数据 + NEXT +PREV
手撕代码(增加+删除)
增加,删除的操作, 需要tmp 停止待操作节点的前一节点上。
查找操作进行了扩展,回调函数(函数指针)。解耦合,扩展功能。
相关的操作代码:
cs
#include "DouLink.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
DouLinkList *CreateDouLinkList()
{
DouLinkList *dl = malloc(sizeof(DouLinkList));
if (NULL == dl)
{
perror("CreateDouLinkList malloc");
return NULL;
}
dl->head = NULL;
dl->clen = 0;
return dl;
}
int InsertHeadDouLinkList(DouLinkList *dl, DATATYPE *data)
{
DouLinkNode *newnode = malloc(sizeof(DouLinkNode));
if (NULL == newnode)
{
perror("InsertHeadDouLinkList malloc");
return 1;
}
memcpy(&newnode->data, data, sizeof(DATATYPE));
newnode->next = NULL;
newnode->prev = NULL;
if (IsEmptyDouLinkList(dl))
{
dl->head = newnode;
}
else
{
newnode->next = dl->head;
dl->head->prev = newnode;
dl->head = newnode;
}
dl->clen++;
return 0;
}
int ShowDouLinkList(DouLinkList *dl, DIRECT direct)
{
DouLinkNode *tmp = dl->head;
if (DIR_FORWARD == direct)
{
while (tmp)
{
printf("name:%s sex:%c age:%d score:%d\n", tmp->data.name, tmp->data.age,
tmp->data.age, tmp->data.score);
tmp = tmp->next;
}
}
else //逆向显示
{
// tmp 会停在最后一个有效元素上
while (tmp->next)
{
tmp = tmp->next;
}
while (tmp)
{
printf("name:%s sex:%c age:%d score:%d\n", tmp->data.name, tmp->data.age,
tmp->data.age, tmp->data.score);
tmp = tmp->prev;
}
}
return 0;
}
int IsEmptyDouLinkList(DouLinkList *dl)
{
return 0 == dl->clen;
}
int InsertTailDouLinkList(DouLinkList *dl, DATATYPE *data)
{
if (IsEmptyDouLinkList(dl))
{
return InsertHeadDouLinkList(dl, data);
}
else
{
DouLinkNode *newnode = malloc(sizeof(DouLinkNode));
if (NULL == newnode)
{
perror("InsertTailDouLinkList malloc");
return 1;
}
memcpy(&newnode->data, data, sizeof(DATATYPE));
newnode->next = NULL;
newnode->prev = NULL;
DouLinkNode *tmp = dl->head;
while (tmp->next)
{
tmp = tmp->next;
}
newnode->prev = tmp;
tmp->next = newnode;
}
dl->clen++;
return 0;
}
int InsertPosDouLinkList(DouLinkList *dl, DATATYPE *data, int pos)
{
int size = GetSizeDouLinkList(dl);
if (pos < 0 || pos > size)
{
printf("InsertPosDouLinkList pos error\n");
return 1;
}
if (0 == pos)
{
return InsertHeadDouLinkList(dl, data);
}
else if (size == pos)
{
return InsertTailDouLinkList(dl, data);
}
else
{
DouLinkNode *newnode = malloc(sizeof(DouLinkNode));
if (NULL == newnode)
{
perror("InsertPosDouLinkList malloc");
return 1;
}
memcpy(&newnode->data, data, sizeof(DATATYPE));
newnode->next = NULL;
newnode->prev = NULL;
DouLinkNode *tmp = dl->head;
while (pos--)
{
tmp = tmp->next;
}
newnode->next = tmp;
newnode->prev = tmp->prev;
tmp->prev = newnode;
newnode->prev->next = newnode;
dl->clen++;
}
return 0;
}
//DouLinkNode *FindDouLinkList(DouLinkList *dl, char *name)
DouLinkNode *FindDouLinkList(DouLinkList *dl,PFUN fun, void*arg)
{
DouLinkNode* tmp = dl->head;
while(tmp)
{
//if(0==strcmp(tmp->data.name,name))
if(fun(&tmp->data,arg))
{
return tmp;
}
tmp=tmp->next;
}
return NULL;
}
int ModifyDouLinkList(DouLinkList *dl, char *name, DATATYPE *newdata);
int DeleteDouLinkList(DouLinkList *dl, char *name);
int GetSizeDouLinkList(DouLinkList *dl)
{
return dl->clen;
}
int DestroyDouLinkList(DouLinkList *dl);
双向链表的逆序:
三个指针分别代表前一个,当前,后一个
cs
int ReverDouLinkList(DouLinkList *dl)
{
if (NULL == dl->head || NULL == dl->head->next)
{
printf("Rever error\n");
return -1;
}
DouLinkNode *prev = NULL;
DouLinkNode *tmp = dl->head;
DouLinkNode *next = NULL;
while (tmp)
{
next = tmp->next;
tmp->next = prev;
tmp->prev = next;
prev = tmp;
tmp = next;
}
dl->head = prev;
return 0;
}