前言:双向循环链表与单向链表的区别是双向链表中有一个前指针,可以指向前面一个链表的地址,最后一个指针指向哨兵位的地址
哨兵位就是相当于一个头节点,但是它只是起到一个链接作用,只负责链接
这里我就画随机插入和删除节点的图,其他的图都是类似就不做过多说明
随机插入需要和寻找相配合(在pos节点的前面插入)
SL* Find(SL* phead,LTDatatype x)//寻找数据
{
SL* tail = phead;
while (tail->data!= x)
{
tail = tail->next;
}
return tail;
}
void Insert(SL* phead, SL* pos, LTDatatype x)//访问位置插入
{
SL* tail = phead;
SL* Newnode = Buynewnode(x);
while (tail->next!= pos)
{
tail = tail->next;
}
Newnode->next = pos;
Newnode->prev = pos->prev;
pos->prev = Newnode;
tail->next = Newnode;
}
随机删除需要和寻找相配合(在pos节点的前面删除)
void Eraser(SL* phead, SL* pos)//删除任意位置数据
{
SL* tail = phead;
while (tail->next != pos)
{
tail = tail->next;
}
SL* after = pos->next;
after->prev = tail;
tail->next = after;
free(pos);
pos->next = NULL;
pos->prev = NULL;
}
下面就是全部源码,与单链表类似但是不完全相同
#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
typedef int LTDatatype;
typedef struct SLTlist
{
LTDatatype data;
struct SLTlist* prev;
struct SLTlist* next;
}SL;
SL* Initlist();//初始化
void PushBack(SL* phead,LTDatatype x);//尾插
void PopBack(SL* phead);//尾删
void PushFront(SL* phead, LTDatatype x);//头插
void PopFront(SL* phead);//头删
void Insert(SL* phead, SL* pos, LTDatatype x);//访问位置插入
void Eraser(SL* phead, SL* pos);//删除任意位置数据
SL* Find(SL* phead,LTDatatype x);//寻找数据
void Print(SL* phead);//打印数据
void Distroy(SL* phead);//销毁数据
#define _CRT_SECURE_NO_WARNINGS 1
#include"SldList.h"
int main()
{
SL* guard = Initlist();
PushBack(guard,6);
PushBack(guard, 5);
PushFront(guard,8);
PushBack(guard, 7);
Insert(guard, Find(guard,8),10);
Eraser(guard, Find(guard, 5));
PopFront(guard);
Print(guard);
return 0;
}
#define _CRT_SECURE_NO_WARNINGS 1
#include"SldList.h"
SL* Buynewnode(LTDatatype x)
{
SL* Newnode = (SL*)malloc(sizeof(SL));
Newnode->data = x;
Newnode->prev = NULL;
Newnode->next = NULL;
return Newnode;
}
SL* Initlist()//初始化
{
SL* guard = (SL*)malloc(sizeof(SL));
guard->prev = guard;
guard->next = guard;
guard->data= -1;
return guard;
}
void Print(SL* phead)//打印数据
{
SL* tail = phead;
while (tail->next != phead)
{
tail = tail->next;
printf("%d->", tail->data);
}
}
void Distroy(SL* phead)//销毁数据
{
SL* tail = phead;
SL* cur = phead;
while (tail->next != phead)
{
cur = tail->next;
free(tail);
tail = cur;
}
}
void PushBack(SL* phead, LTDatatype x)//尾插
{
//SL* tail = phead;
//SL* Newnode = Buynewnode(x);
//while (tail->next!=phead)
//{
// tail = tail->next;
//}
//Newnode->prev = tail;
//Newnode->next = phead;
//phead->prev = Newnode;
//tail->next = Newnode;
SL* end = phead->prev;
Insert(phead, Find(phead,end->data),x);
}
void PopBack(SL* phead)//尾删
{
assert(phead);
assert(phead->next!=phead->prev);
//SL* tail = phead;
//while (tail->next!= phead)
//{
// tail = tail->next;
//}
//SL* prevtail = tail->prev;
//phead->prev = prevtail;
//prevtail->next = tail->next;
//free(tail);
//tail->next = NULL;
//tail->prev = NULL;
SL* end = phead->prev;
Eraser(phead,Find(phead, end->data));
}
void PushFront(SL* phead, LTDatatype x)//头插
{
//assert(phead);
//SL* tail = phead;
//SL* Newnode = Buynewnode(x);
//SL* first = tail->next;
//tail->next = Newnode;
//Newnode->prev = tail;
//Newnode->next = first;
//first->prev = Newnode;
SL* first = phead->next;
Insert(phead, Find(phead, first->data),x);
}
void PopFront(SL* phead)//头删
{
//方法1:
//assert(phead->next!=phead);
//SL* tail = phead;
//SL* first = phead->next;
//SL* second = first->next;
//tail->next =second;
//second->prev = tail;
//free(first);
//first->next = NULL;
//first->prev = NULL;
//方法2:
SL* first = phead->next;
Eraser(phead,Find(phead,first->data));//删除任意位置数据
}
SL* Find(SL* phead,LTDatatype x)//寻找数据
{
SL* tail = phead;
while (tail->data!= x)
{
tail = tail->next;
}
return tail;
}
void Insert(SL* phead, SL* pos, LTDatatype x)//访问位置插入
{
SL* tail = phead;
SL* Newnode = Buynewnode(x);
while (tail->next!= pos)
{
tail = tail->next;
}
Newnode->next = pos;
Newnode->prev = pos->prev;
pos->prev = Newnode;
tail->next = Newnode;
}
void Eraser(SL* phead, SL* pos)//删除任意位置数据
{
SL* tail = phead;
while (tail->next != pos)
{
tail = tail->next;
}
SL* after = pos->next;
after->prev = tail;
tail->next = after;
free(pos);
pos->next = NULL;
pos->prev = NULL;
}