# 双向带头链表实现

1. 节点中存储的值

2.逻辑实现

1. 创建节点函数

2. 初始化哨兵位

3. 尾插

4. 头插

5. 尾删

6. 头删

7. 打印链表值

8. 查找数据，返回节点地址

9. 指定地址后插入节点

10. 删除指定地址节点

11. 销毁链表

1. list.h

2. list.c

3. 测试

qrev是上一个节点的地址

data是节点中存储的数据

next是下一个节点的位置

第一个节点为哨兵位不存储数据

#### 二. 各种功能实现

###### 1. 创建节点函数
``````ListNode* BuyListNode(DataType x)
{
ListNode* newnode = (ListNode*)malloc(sizeof(ListNode));
if (newnode == NULL)
{
exit(-1);
}
newnode->data = x;
newnode->next = newnode->prev = newnode;
return newnode;
}``````
###### 2. 初始化哨兵位

``````void ListNodeInit(ListNode** pphead)
{
}
``````
###### 3. 尾插
``````void ListNodePushBack(ListNode* phead, DataType x)
{

tail->next = newnode;//之前的尾指向现在的尾
}``````
###### 4. 头插
``````void ListNodePushFront(ListNode* head,DataType x)
{

first->prev = newnode;

}
``````
###### 5. 尾删
``````void ListNodePopBack(ListNode* head)
{
ListNode* newtail = tail->prev;
free(tail);
tail = NULL;
}``````
###### 6. 头删
``````void ListNodePopFront(ListNode* head)
{
ListNode* newfirst = first->next;

free(first);
first = NULL;
}``````
###### 7. 打印链表值
``````void ListNodePrint(ListNode* phead)
{
{
printf("%d  ", tmp->data);
tmp = tmp->next;
}
}``````
###### 8. 查找数据，返回节点地址
``````ListNode* ListNodeFind(ListNode* head,DataType x)
{
{
if (tmp->data == x)
return tmp;
tmp = tmp->next;
}
return NULL;
}``````
###### 9. 指定地址后插入节点
``````void ListNodeInsert(ListNode* pos, DataType x)
{
assert(pos);
ListNode* newnext = pos->next;

newnode->prev = pos;
newnode->next = newnext;

pos->next = newnode;
newnext->prev = newnode;

}``````
###### 10. 删除指定地址节点
``````void ListNodeErase(ListNode* pos)
{
assert(pos);
ListNode* posprev = pos->prev, * posnext = pos->next;
posprev->next = posnext;
posnext->prev = posprev;
free(pos);
pos = NULL;
}``````
###### 11. 销毁链表
``````void ListNodeDestroy(ListNode* head)
{
{
ListNode* next = cur->next;
free(cur);
cur = next;
}
}``````

#### 三. 完整代码

###### 1. list.h
``````#define _CRT_SECURE_NO_WARNINGS h
#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>

typedef int DataType;

typedef struct ListNode
{
DataType data;
struct SList* next;
struct SList* prev;
}ListNode;

//初始化
//尾插
//打印链表
//头插
//尾删
//头删
//查找数据
//指定位置后插入
void ListNodeInsert(ListNode* pos, DataType x);
//指定位置删除
void ListNodeErase(ListNode* pos);
//销毁链表
###### 2. list.c
``````#define _CRT_SECURE_NO_WARNINGS h

#include"list.h"

{
ListNode* newnode = (ListNode*)malloc(sizeof(ListNode));
if (newnode == NULL)
{
exit(-1);
}
newnode->data = x;
newnode->next = newnode->prev = newnode;
return newnode;
}

{
}

{

tail->next = newnode;//之前的尾指向现在的尾
}

{
{
printf("%d  ", tmp->data);
tmp = tmp->next;
}
}

{

first->prev = newnode;

}

{
ListNode* newtail = tail->prev;
free(tail);
tail = NULL;
}

{
ListNode* newfirst = first->next;

free(first);
first = NULL;
}

{
{
if (tmp->data == x)
return tmp;
tmp = tmp->next;
}
return NULL;
}

void ListNodeInsert(ListNode* pos, DataType x)
{
assert(pos);
ListNode* newnext = pos->next;

newnode->prev = pos;
newnode->next = newnext;

pos->next = newnode;
newnext->prev = newnode;

}

void ListNodeErase(ListNode* pos)
{
assert(pos);
ListNode* posprev = pos->prev, * posnext = pos->next;
posprev->next = posnext;
posnext->prev = posprev;
free(pos);
pos = NULL;
}

{
{
ListNode* next = cur->next;
free(cur);
cur = next;
}
}``````
###### 3. 测试
``````#define _CRT_SECURE_NO_WARNINGS h

#include"list.h"
void test()
{
ListNodeInsert(find, 666);
printf("n");
ListNodeErase(find);

}

int main()
{
test();
}``````

（づ￣3￣）づ╭❤～

THE END