一、双向链表
1.定义
双向链表是在单链表的每个结点中,再设置一个指向其钱去节点的指针域。
typedef struct DulNode
{
ElemType date;
struct DulNode *pri;//直接前驱指针
sturct DulNode *next;//直接后继指针
}DulNode,*DuLinkList;
2.双向链表的创建
struct DouLinkList* CreateDouLinkList()
{
struct DouLinkList*dl = malloc(sizeof(struct DouLinkList));
if(NULL == dl)
{
fprintf(stderr, "CreatDouLinkList malloc");
return NULL;
}
dl->head =NULL;
dl->clen = 0;
return dl;
}
3.双向链表的插入
(1)头插
int InsertHeadDouLinkList(struct DouLinkList*dl,struct DATATYPE*data)
{
struct DouNode*newnode = malloc(sizeof( struct DouNode));
if(NULL == newnode)
{
fprintf(stderr, "InsertHeadDouLinkList malloc");
return 1;
}
memcpy(&newnode->data,data,sizeof(struct DATATYPE));
newnode->next = NULL;
newnode->prev = NULL;
newnode->next =dl->head;
if(dl->head)
{
dl->head->prev =newnode;
}
dl->head = newnode;
dl->clen++;
return 0;
}
(2)尾插
int InsertTailDouLinkList(struct DouLinkList*dl,struct DATATYPE*data)
{
if(IsEmptyDouLinkList(dl))
{
return InsertHeadDouLinkList(dl,data);
}
else
{
struct DouNode*tmp = dl->head;
while(tmp->next)
{
tmp = tmp->next;
}
struct DouNode*newnode = malloc(sizeof( struct DouNode));
if(NULL == newnode)
{
fprintf(stderr, "InsertTailDouLinkList malloc");
return 1;
}
//初始化节点
memcpy(&newnode->data,data,sizeof(struct DATATYPE));
newnode->next = NULL;
newnode->prev = NULL;
//连接链表
newnode->prev = tmp;
tmp->next = newnode;
dl->clen++;
}
return 0;
}
(3) 任意位置插
int InsertPosDouLinkList(struct DouLinkList*dl,struct DATATYPE*data,int pos)
{
int len = GetSizeDouLinkList(dl);
if(pos<0||pos>len)
{
return 1;
}
if(0 == pos)
{
return InsertHeadDouLinkList(dl,data);
}
else if(pos == len)
{
return InsertTailDouLinkList(dl, data);
}
else
{
struct DouNode*newnode = malloc(sizeof( struct DouNode));
if(NULL == newnode)
{
fprintf(stderr, "InsertPosDouLinkList malloc");
return 1;
}
//初始化节点
memcpy(&newnode->data,data,sizeof(struct DATATYPE));
newnode->next = NULL;
newnode->prev = NULL;
struct DouNode*tmp = dl->head;
int i = 0;
for(i = 0;i < pos;++i)
{
tmp = tmp->next;
}
newnode->next=tmp;
newnode->prev=tmp->prev;
tmp->prev=newnode;
newnode->prev->next=newnode;
}
return 0;
}
4.双向链表的遍历
int ShowDouLinkList(struct DouLinkList*dl,DIR dir)
{
struct DouNode*tmp = dl->head;
if(FORWADR == dir)
{
while (tmp)
{
printf("%s %c %d %d\n",tmp->data.name,tmp->data.sex,tmp->data.age,tmp->data.score);
tmp=tmp->next;
}
}
else if(BACKWADR == dir)
{
while(tmp->next)
{
tmp=tmp->next;
}
while(tmp)
{
printf("%s %c %d %d\n",tmp->data.name,tmp->data.sex,tmp->data.age,tmp->data.score);
tmp =tmp->prev;
}
}
return 0;
}
5. vi Makefile(工程管理工具) :三个.c以上可使用
方法一:
a.out(目标):main.c ./doulink (依赖)
gcc main.c doulink.c//前面空一个Tab键
clean:
rm a.out
在终端敲make,进行编译,若要指定makefile ,加-f再加指定makefile
方法二:
#代表源文件
SRC += main.c(变量名任取)//指定变量
SRC += doulink.c
DST = app(可执行文件)
CC = gcc//编译器
FLAG = -g
LIB = -lm
$(DST):$(SRC)
$(CC) $(SRC) $(FLAG) $(LIB)-o(指定名字) $(DST)
clean:
rm $(DST)
6.双向链表的查找
struct DouNode * FindDouLinkList(struct DouLinkList*dl,char*name)
{
if(IsEmptyDouLinkList(dl))
{
return NULL;
}
struct DouNode*tmp = dl->head;
while(tmp)
{
if(0 == strcmp(tmp->data.name,name))
{
return tmp;
}
tmp = tmp->next;
}
return NULL;
}
7.双向链表的修改
int ModifyDouLinkList(struct DouLinkList*dl,char*name,struct DATATYPE*data)
{
struct DouNode*tmp = FindDouLinkList(dl, name);
if(NULL == tmp)
{
return 1;
}
memcpy(&tmp->data, data,sizeof(struct DATATYPE));
return 0;
}
8.双向链表的销毁
int DestoryDouLinkList(struct DouLinkList*dl)
{
while(1)
{
struct DouNode*tmp = dl->head;
if(NULL == tmp)
{
break;
}
dl->head = dl->head->next;
free(tmp);
}
free(dl);
dl = NULL;
return 0;
}
9.双向链表的删除
int DeleteDouLinkList(struct DouLinkList*dl,char*name)
{
if(IsEmptyDouLinkList(dl))
{
return 1;
}
struct DouNode*tmp = FindDouLinkList(dl, name);
if(tmp ==dl->head)
{
dl->head =dl->head->next;
tmp->next->prev = NULL;
free(tmp);
}
else if(NULL == tmp->next)
{
tmp->prev->next = NULL;
free(tmp);
}
else
{
tmp->next->prev = tmp->prev;
tmp->prev->next = tmp->next;
free(tmp);
}
dl->clen--;
return 0;
}
10.双向链表的逆序
int ReverseDouLinkList(struct DouLinkList*dl)
{
struct DouNode*prev = NULL;
struct DouNode*tmp = dl->head;
struct DouNode*next = tmp->next;
int len = GetSizeDouLinkList(dl);
if(len < 2)
{
return 1;
}
while(1)
{
tmp->next = prev;
tmp->prev = next;
prev = tmp;
tmp = next;
if(NULL == tmp)
{
break;
}
else
{
next = next->next;
}
}
dl->head = prev;
return 0;
}