在单链表中,我们有了next指针,这就使得我们要查询的下一个节点的时间复杂度为O(1),可是我们要找的是上一个节点的话,那么最坏的情况就是O(n)了,因为我们每次都要从头开始查找。为了改善查找的时间复杂度,就有了现在的双向链表。
双向链表:就是在单链表的每个节点中加入一个指向其前驱的指针域。所以在双向链表的每个节点中存在两个指针域,一个指向前驱,一个指向后继。
双向链表的实现基本上与单链表的实现一致,就是多了一个指向其前驱的指针,在写的时候要注意其前驱指针。
#include<stdio.h>
#include<assert.h>
#include<stdlib.h>
typedef struct DNode
{
int data;
struct DNode *pre;
struct DNode *next;
}DNode,*Dlist;
//初始化
void initList(Dlist list)
{
assert(list != nullptr);
list->pre = nullptr;
list->next = nullptr;
}
//创建一个节点
DNode* create(int val)
{
DNode * node = (DNode *)malloc(sizeof(DNode));
assert(node != nullptr);
node->data = val;
node->pre = nullptr;
node->next = nullptr;
return node;
}
//头插
bool headInsert(Dlist list, int val)
{
assert(list != nullptr);
DNode *Get = create(val);
Get->pre = list;
Get->next = list->next;
list->next = Get;
return true;
}
//尾插
bool tailInsert(Dlist list, int val)
{
assert(list != nullptr);
DNode *cur = list;
while (cur->next != nullptr) //err
{
cur = cur->next;
}
DNode *Get = create(val);
//Get->next = nullptr;
cur->next = Get;
Get->pre = cur;
return true;
}
//长度
int Length(Dlist list)
{
assert(list != nullptr);
DNode *cur = list;
int count = 0;
while (cur->next != nullptr)
{
count++;
cur = cur->next;
}
return count;
}
bool isEmpty(Dlist list)
{
assert(list != nullptr);
if (list->next == nullptr)
{
return true;
}
return false;
}
//pos位置插入
bool insert(Dlist list, int pos, int val)
{
assert(list != nullptr);
if (pos > Length(list) && pos < 0)
{
return false;
}
DNode *cur = list;
for (int i = 1; i < pos; ++i)
{
cur = cur->next;
}
DNode *get = create(val);
get->next = cur->next;
cur->next = get;
get->pre = cur;
return true;
}
//show
void Show(Dlist list)
{
assert(list != nullptr);
DNode *cur = list->next;
while (cur != nullptr)
{
printf("%d ", cur->data);
cur = cur->next;
}
printf("\n");
}
//查询是否存在
DNode* Find(Dlist list, int val)
{
assert(list != nullptr);
DNode *cur = list;
while (cur->next != nullptr)
{
if (cur->next->data == val)
{
//printf("exist\n");
return cur;
}
cur = cur->next;
}
//printf("no\n");
return nullptr;
}
//值删除
bool Delete(Dlist list, int val)
{
assert(list != nullptr);
DNode *p = Find(list, val);
if (p == nullptr)
{
printf("没有该值\n");
return false;
}
DNode *cur = p->next;
p->next = cur->next;
if (p->next != nullptr)
{
cur->next->pre = p;
free(cur);
}
else
{
free(cur);
}
cur = nullptr;
return true;
}
//pos位置删除
bool posDelete(Dlist list, int pos)
{
assert(list != nullptr);
if (pos<0 && pos>Length(list))
{
return false;
}
DNode *cur = list;
for (int i = 0; i < pos; ++i)
{
cur = cur->next;
}
DNode *p = cur->pre;
p->next = cur->next;
if (p->next != nullptr)
{
cur->next->pre = p;
free(cur);
}
else
{
free(cur);
}
cur = nullptr;
return true;
}
//释放
void Destory(Dlist list)
{
DNode *del = nullptr;
while (list->next != nullptr)
{
del = list->next;
list->next = del->next;
free(del);
}
del = nullptr;
}
test
int main()
{
DNode head;
initList(&head);
for (int i = 1; i < 10; ++i)
{
tailInsert(&head, i);
}
Show(&head);
insert(&head, 3, 99);
Show(&head);
posDelete(&head, 10);
Show(&head);
int len = Length(&head);
printf("%d\n", len);
Destory(&head);
return 0;
}