一.链表的初始化
#pragma once
#include<stdio.h>
#include<assert.h>
#include<stdlib.h>
#include<stdbool.h>
typedef int DatatypeSTlist;
typedef struct List
{
struct List* next;
struct List* prev;
DatatypeSTlist val;
}ListNode;
ListNode* ListCreate();//创建头节点
ListNode* ListCreate()//创建头节点也是链表的初始化
{
ListNode* phead = (ListNode*)malloc(sizeof(ListNode));
assert(phead);
phead->next = phead;
phead->prev = phead;
return phead;
}
然后我们写个创建空白节点的函数,方便我们在对链表进行插入操作时更加方便,只需要调用一下函数就可以创建一个节点出来,下面是代码演示
ListNode* BuyNode(DatatypeSTlist x)//创建空白节点
{
ListNode* newnode = (ListNode*)malloc(sizeof(ListNode));
assert(newnode);
newnode->next = NULL;
newnode->prev = NULL;
newnode->val = x;
return newnode;
}
如果要对链表进行调试测试的话,同时还要简便的看到代码的效果,我们可以写一个链表的打印,打印出来可以更加明显的看出效果
void Listprint(ListNode* phead)//双向链表的打印
{
assert(phead);
ListNode* cur = phead->next;
printf("phead");
while (cur!=phead)
{
printf("->%d");
cur = cur->next;
}
printf("\n");
}
下面实现链表的查找功能
ListNode* ListFind(DatatypeSTlist x)//查找所输入的值是否存在并返回
{
ListNode* cur = phead->next;
while (cur != phead)
{
if (cur->val == x)
return cur;
cur = cur->next;
}
return NULL;
}
接下来就是实现这个链表最重要的功能了,删除和插入,这里我们一起展示
void ListInsert(ListNode* pos, DatatypeSTlist x)//在pos位置前插入一个数据
{
ListNode* newnode = BuyNode(x);
ListNode* prev = pos->prev;
ListNode* next = pos->next;
newnode->prev = prev;
newnode->next = next;
pos->prev = newnode;
prev->next = newnode;
}
void ListErase(ListNode* pos)//删除pos位置的节点
{
ListNode* prev = pos->prev;
ListNode* next = pos->next;
prev->next = next;
next->prev = prev;
free(pos);
}
请注意,我这里实现的是一个链表的通用方式,如果想实现头插头删,只需要往链表里传参穿phead->next即可,如果是实现尾插尾删,则需要传参phead->prev即可,比起单链表方便的不知一星半点;