双向链表总结
Posted 菜鸟沃土
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了双向链表总结相关的知识,希望对你有一定的参考价值。
基本数据结构之-双向链表
双向链表和单向链表明显的区别就是,双向链表可以向前查找,也就是能直接找到它自己的前驱结点,但是双向链表不是循环链表!
分析基本的数据结构,每个结点都有自己的数据域和两个指针域,一个指向前驱,一个指向后继,但是为了通用性,我们只考虑一个前驱和一个后继的关系
typedef struct _DOUBLE_LIST_NODE
{
// 定义双向链表的前驱和后继
struct _DOUBLE_LIST_NODE *Pre;
struct _DOUBLE_LIST_NODE *Next;
}DoubleListNode, *DoubleSidedList;
// 初始化
int Init_DoubleSidedList(DoubleSidedList *doublesidedlist)
{
if (doublesidedlist == NULL)
{
exit(-1);
}
if (*doublesidedlist == NULL)
{
*doublesidedlist = (DoubleSidedList)malloc(sizeof(DoubleListNode));
}
(*doublesidedlist)->Next = NULL;
(*doublesidedlist)->Pre = NULL;
return 0;
}
// 销毁,不要释放其他位置的空间,不知道是栈内存还是堆内存,并且不知道是什么数据类型
void Destroy_DoubleSidedList(DoubleSidedList doublesidedlist)
{
if (doublesidedlist == NULL)
{
return;
}
free(doublesidedlist);
}
// 仅仅是把指针置空
void Clear_DoubleSidedList(DoubleSidedList doublesidedlist)
{
if (doublesidedlist == NULL)
{
return;
}
doublesidedlist->Next = NULL;
doublesidedlist->Pre = NULL;
}
int Empty_DoubleSidedList(DoubleSidedList doublesidedlist)
{
if (doublesidedlist==NULL)
{
return -1;
}
// 如果next为空,肯定链表也是空的
return doublesidedlist->Next == NULL;
//
}
// 返回当前双向链表的长度
int Length_DoubleSidedList(DoubleSidedList doublesidedlist)
{
if (doublesidedlist == NULL)
{
return 0;
}
int length = 0;
// 第一个元素的开始的位置在 定义Next开始
DoubleListNode *pCurrent =doublesidedlist->Next;
while (pCurrent!= NULL)
{
++length;
pCurrent = pCurrent->Next;
}
return length;
}
void * GetElem_DoubleSidedList(DoubleSidedList doublesidedlist, int Pos)
{
if (doublesidedlist == NULL)
{
return NULL;
}
if (Pos<0 || Pos>Length_DoubleSidedList(doublesidedlist)-1)
{
return NULL;
}
DoubleListNode *pCurrent = doublesidedlist->Next;
int i = 0;
while (i<Pos)
{
pCurrent = pCurrent->Next;
++i;
}
// 返回所在的位置 从 0 开始
return pCurrent;
}
// 查看链表中是否存在某个值,返回所在的位置
int LocateElem_DoubleSidedList(DoubleSidedList doublesidedlist, void* data, int(*compare)(void *data1, void *data2))
{
if (doublesidedlist==NULL)
{
return -1;
}
if (data == NULL)
{
return -2;
}
if (compare == NULL)
{
return -4;
}
DoubleListNode *Node = (DoubleListNode *)data;
int i = 0;
DoubleListNode *pCurrent = doublesidedlist->Next;
while (pCurrent!= NULL)
{
// 必须要传入比较函数
if (compare(pCurrent, Node))
{
return i;
}
pCurrent = pCurrent->Next;
++i;
}
return -3;
}
// 返回前驱,这儿就可以体现出双向链表的优势
void *PriorElem_DoubleSidedList(DoubleSidedList doublesidedlist, void *data)
{
if (doublesidedlist == NULL)
{
return NULL;
}
if (data == NULL)
{
return NULL;
}
DoubleListNode *pCurrent = doublesidedlist->Next;
while (pCurrent != NULL)
{
#if 0
if (pCurrent->Next==data)
{
return pCurrent;
}
#else
if (pCurrent == data)
{
//这就是双向链表的好处
return pCurrent->Pre;
}
#endif
pCurrent = pCurrent->Next;
}
return NULL;
}
// 返回后继
void* NextElem_DoubleSidedList(DoubleSidedList doublesidedlist, void *data)
{
if (doublesidedlist == NULL)
{
return NULL;
}
if (data == NULL)
{
return NULL;
}
DoubleListNode *pCurrent = doublesidedlist;
while (pCurrent->Next != NULL)
{
if (pCurrent == data)
{
return pCurrent->Next;
}
pCurrent = pCurrent->Next;
}
return NULL;
}
// 插入操作,一定要考虑特殊的情况
int Insert_DoubleSidedList(DoubleSidedList doublesidedlist, int Pos, void * data)
{
if (doublesidedlist == NULL)
{
return -1;
}
if (data == NULL)
{
return -2;
}
if (Pos < 0)
{
Pos = 0;
}
if (Pos > Length_DoubleSidedList(doublesidedlist))
{
Pos = Length_DoubleSidedList(doublesidedlist);
}
DoubleListNode *pCurrent = doublesidedlist;
for (int i = 0; i < Pos; ++i)
{
pCurrent = pCurrent->Next;
}
DoubleListNode *Node = (DoubleListNode *)data;
//
if (Pos==0 && Length_DoubleSidedList(doublesidedlist) == 0)
{
// 最前面一个位置插入 && 当前长度为0 插入的结点不存在后继结点
Node->Next = pCurrent->Next;
Node->Pre = pCurrent;
pCurrent->Next = Node;
}
else if (Length_DoubleSidedList(doublesidedlist) == Pos)
{
// 最后一个结点不存在后继结点
Node->Next = pCurrent->Next;
Node->Pre = pCurrent;
pCurrent->Next = Node;
}
else
{
Node->Next = pCurrent->Next;
pCurrent->Next->Pre = Node;
pCurrent->Next = Node;
Node->Pre = pCurrent;
}
return 0;
}
// 删除操作 一定要考虑特殊的情况
int DeleteByPos_DoubleSidedList(DoubleSidedList doublesidedlist, int Pos)
{
if (doublesidedlist == NULL)
{
return -1;
}
if (Pos<0 || Pos>Length_DoubleSidedList(doublesidedlist) - 1)
{
return -2;
}
DoubleListNode *pCurrent = doublesidedlist->Next;
// 找到前驱
for (int i = 0; i < Pos; ++i)
{
pCurrent = pCurrent->Next;
}
// 如果删除的是最后一个结点,那么找不到最后一个结点的下一个结点
if (Pos == Length_DoubleSidedList(doublesidedlist))
{
pCurrent->Pre->Next = NULL;
}
else
{
pCurrent->Next->Pre = pCurrent;
pCurrent->Next = pCurrent->Next->Next;
}
return 0;
}
int DeleteByVal_DoubleSidedList(DoubleSidedList doublesidedlist, void* data)
{
if (doublesidedlist == NULL)
{
return -1;
}
DoubleListNode *pCurrent = doublesidedlist->Next;
while (pCurrent->Next != NULL )
{
if (pCurrent == data)
{
break;
}
pCurrent = pCurrent->Next;
}
// 如果是最后一个结点,
if (pCurrent->Next == NULL)
{
pCurrent->Pre->Next = NULL;
}
else
{
pCurrent->Next->Pre = pCurrent;
pCurrent->Next = pCurrent->Next->Next;
}
return 0;
}
// 遍历操作
void Traverse_DoubleSidedList(DoubleSidedList doublesidedlist, void(*Traverse)(void *data))
{
if (doublesidedlist == NULL)
{
return;
}
if (Traverse == NULL)
{
return;
}
DoubleListNode *pCurrent = doublesidedlist->Next;
while (pCurrent != NULL)
{
Traverse(pCurrent);
pCurrent = pCurrent->Next;
}
}
以上是关于双向链表总结的主要内容,如果未能解决你的问题,请参考以下文章