双向链表其实与单链表及其相像,无非是多了一个访问的方向
我们先来看看双向链表的单一个体
![](https://img-blog.csdnimg.cn/img_convert/c38cc0d88102c1147f49bf9dce0a3dc9.png)
与单链表很像吧,就多了一个pre前驱指针,然后我们再来看看双向链表的全貌
![](https://img-blog.csdnimg.cn/img_convert/b9f970ce362232b637674e7d76ba1c09.png)
接下来就开始双向链表的代码
首先要先定义单一个体
typedef struct Node
{
int data;
struct Node* pre;
struct Node* next;
}NODE,*LPNODE;
由于我们的双向链表有两个类似于单链表的头节点,即有两个入口,这意味这我们进行任何操作都有两种选择,在双向链表中我们经常用封装的形式去形容它,如下
typedef struct list //描述双向链表
{
LPNODE firstNode;//头节点
LPNODE lastNode;//尾节点
int listsize;
}LIST;
接下来是对双向链表的基本操作
NODE* creatNode(int data)//创建节点
{
LPNODE newNode = (LPNODE)malloc(sizeof(NODE));
assert(newNode);
newNode->data = data;
newNode->next = NULL;
newNode->pre = NULL;
return newNode;
}
LIST* creatList()
{
LIST* List = (LIST*)malloc(sizeof(LIST));
assert(List);//malloc内存如果申请失败,返回NULL值
List->firstNode = NULL;
List->lastNode = NULL;
List->listsize = 0;
return List;
}
void push_front(LIST* list,int data)
{
LPNODE newNode = creatNode(data);
if (list->listsize == 0)//第一次插入时,新节点时第一个也是第二个
{
list->lastNode = newNode;
//list->firstNode = newNode;
//list->listsize++;
}
else
{
newNode->next = list->firstNode;
list->firstNode->pre = newNode;
//list->firstNode = newNode;
//list->listsize++;
}
//简化代码,减少代码量
list->firstNode = newNode;
list->listsize++;
}
void push_back(LIST* list, int data)
{
LPNODE newNode = creatNode(data);
if (list->listsize == 0)//第一次插入时,新节点时第一个也是第二个
{
list->firstNode = newNode;
//list->lastNode = newNode;
//list->listsize++;
}
else
{
newNode->pre = list->lastNode;
list->lastNode->next = newNode;
//list->lastNode = newNode;
//list->listsize++;
}
list->lastNode = newNode;
list->listsize++;
}
void push_point(LIST* list, int data, int pointdata)
{
LPNODE pointNode = list->firstNode;
LPNODE preNode = NULL;
while (pointNode != NULL && pointNode->data != pointdata)
{
preNode = pointNode;
pointNode = pointNode->next;
}
if (pointNode == NULL)
{
printf("没找到\n");
return;
}
else if (pointNode == list->firstNode)
{
push_front(list, data);
}
else
{
LPNODE newNode = creatNode(data);
preNode->next = newNode;
newNode->pre = preNode;
newNode->next = pointNode;
pointNode->pre = newNode;
list->listsize++;
}
}
void del_front(LIST* list)
{
assert(list);
if (list->listsize == 0)
{
printf("链表为空,无法删除");
return;
}
if (list->listsize == 1)
{
free(list->firstNode);
list->firstNode = NULL;
list->lastNode = NULL;
list->listsize--;
printf("over!");
return;
}
LPNODE temp = list->firstNode;
list->firstNode = temp->next;
list->firstNode->pre = NULL;
temp->next = NULL;
free(temp);
temp = NULL;
list->listsize--;
}
void del_back(LIST* list)
{
assert(list);
if (list->listsize == 0)
{
printf("链表为空,无法删除");
return;
}
if (list->listsize == 1)
{
free(list->lastNode);
list->lastNode = NULL;
list->listsize--;
return;
}
LPNODE temp = list->lastNode;
list->lastNode = temp->pre;
list->lastNode->next = NULL;
temp->pre = NULL;
free(temp);
temp = NULL;
list->listsize--;
}
void del_point(LIST* list, int pointdata)
{
if (list->listsize == 0)
{
printf("链表为空,无法删除");
return;
}
LPNODE pointNode = list->firstNode;
LPNODE preNode = NULL;
while (pointNode != NULL && pointNode->data != pointdata)
{
preNode = pointNode;
pointNode = pointNode->next;
}
if (pointNode == NULL)
{
printf("没找到\n");
return;
}
else if (pointNode == list->firstNode)
{
del_back(list);
}
else
{
preNode->next = pointNode->next;
pointNode->next->pre = preNode;
pointNode->next = NULL;
pointNode->pre = NULL;
free(pointNode);
pointNode = NULL;
list->listsize--;
}
}
void print_front(LIST* list)//从头部开始打印
{
LPNODE pmove = list->firstNode;
while (pmove != NULL)
{
printf("%d\t", pmove->data);
pmove = pmove->next;
}
printf("\n");
}
void print_back(LIST* list)//从尾部开始打印
{
LPNODE pmove = list->lastNode;
while (pmove != NULL)
{
printf("%d\t", pmove->data);
pmove = pmove->pre;
}
printf("\n");
}
到这里就结束了,还希望各位将来的佬能给我一个小赞👍。
我是沈亦,我们一起学习。