双向链表的设计与实现
程序员文章站
2022-03-24 18:22:16
...
1.双向链表可以完成普通链表的所有操作,并且解决了普通链表逆向遍历效率低的问题。
双向链表相对于普通链表没有多大提示,需要注意的就是插入删除操作时的异常处理,
插入删除0号节点的异常,第一次插入的异常,最后一次删除的异常。
dlinklist.h文件
#pragma once
#include "stdio.h"
#include "stdlib.h"
#include "string.h"
typedef void DLinkList;
typedef struct _tag_DLinkListNode
{
struct _tag_DLinkListNode* next;
struct _tag_DLinkListNode* pre;
}DLinkListNode;
typedef struct _tag_DLinkList
{
int length;
DLinkListNode header;
DLinkListNode* slider;
}TDLinkList;
DLinkList* DLinkList_Create();
void DLinkList_Destroy(DLinkList* list);
void DLinkList_Clear(DLinkList* list);
int DLinkList_Length(DLinkList* list);
int DLinkList_Insert(DLinkList* list, DLinkListNode* node,int pos);
DLinkListNode* DLinkList_Get(DLinkList* list,int pos);
DLinkListNode* DLinkList_Delete(DLinkList* list,int pos);
DLinkListNode* DLinkList_DeleteNode(DLinkList* list,DLinkListNode* node);
DLinkListNode* DLinkList_Reset(DLinkList* list);
DLinkListNode* DLinkList_Current(DLinkList* list);
DLinkListNode* DLinkList_Next(DLinkList* list);
DLinkListNode* DLinkList_Pre(DLinkList* list);
dlinklist.c文件
#include "dlinklist.h"
DLinkList* DLinkList_Create()
{
TDLinkList* list = NULL;
list = (TDLinkList*)malloc(sizeof(TDLinkList));
memset(list, 0, sizeof(TDLinkList));
return list;
}
void DLinkList_Destroy(DLinkList* list)
{
TDLinkList *tmp = NULL;
tmp = (TDLinkList *)list;
if (NULL == list)
{
printf("func err DLinkList_Destroy()\n");
}
//2 释放头结点空间
if (tmp != NULL)
{
free(tmp);
}
return;
}
void DLinkList_Clear(DLinkList* list)
{
TDLinkList *tmp = NULL;
tmp = (TDLinkList *)list;
if (NULL == list)
{
printf("func err DLinkList_Clear()\n");
}
//2 清空链表
tmp->header.next = NULL;
tmp->header.pre = NULL;
tmp->slider = NULL;
tmp->length = 0;
return;
}
int DLinkList_Length(DLinkList* list)
{
TDLinkList* rList = NULL;
if (list == NULL)
{
printf("Length:list is NULL\n");
return -1;
}
rList = (TDLinkList*)list;
return rList->length;
}
DLinkListNode* DLinkList_Get(DLinkList* list, int pos)
{
TDLinkList* rList = NULL;
DLinkListNode* current = NULL;
int i = 0;
if (list == NULL || pos < 0)
{
printf("Get:list is NULL or pos < 0\n");
return NULL;
}
rList = (TDLinkList*)list;
current = &(rList->header);
for (i = 0; i < pos; i++)
{
current = current->next;
}
return current->next;
}
int DLinkList_Insert(DLinkList* list, DLinkListNode* node, int pos)
{
int ret = 0, i = 0;
TDLinkList* sList = (TDLinkList*)list;
if (list == NULL || node == NULL || pos < 0)
{
printf("Insert:list is NULL or node is NULL or pos<0");
return -1;
}
DLinkListNode* current = &(sList->header);
DLinkListNode* next = NULL;
for (i=0;i<pos && current->next != NULL;i++)
{
current = current->next;
}
next = current->next;
current->next = node;
node->next = next;
if (next != NULL)//当链表插入第一个元素时,需要特殊处理
{
next->pre = node;
}
node->pre = current;
if (sList->length == 0)
{
sList->slider = node;//当链表插入第一个元素处理游标
}
//若在0位置插入,需要特殊处理,新结点next前pre指向null
if (current == &(sList->header))
{
node->pre = NULL;
}
sList->length++;
return ret;
}
//删除最后一个节点时需要特殊处理
DLinkListNode* DLinkList_Delete(DLinkList* list, int pos)
{
int i = 0;
TDLinkList* sList = (TDLinkList*)list;
DLinkListNode* ret = NULL;
if (list == NULL || pos < 0)
{
printf("Delete:list is NULL or node is NULL or pos<0");
return NULL;
}
DLinkListNode* current = &(sList->header);
DLinkListNode* next = NULL;
for (i = 0; i < pos && current->next != NULL; i++)
{
current = current->next;
}
ret = current->next;
next = ret->next;
current->next = next;
if (next != NULL)//需要特殊处理
{
next->pre = current;
if (current == &(sList->header))
{
next->pre = NULL;
}
}
if (sList->slider == ret)
{
sList->slider = next;
}
sList->length--;
return ret;
}
DLinkListNode* DLinkList_DeleteNode(DLinkList* list, DLinkListNode* node)
{
TDLinkList* sList = (TDLinkList*)list;
DLinkListNode* ret = NULL;
int i = 0;
if (sList != NULL)
{
DLinkListNode* current = &(sList->header);
//查找node在循环链表中的位置
for (i = 0; i < sList->length; i++)
{
if (current->next == node)
{
ret = current->next;
break;
}
current = current->next;
}
//如果ret找到,根据i去删除
if (ret != NULL)
{
DLinkList_Delete(list, i);
}
}
return ret;
}
DLinkListNode* DLinkList_Reset(DLinkList* list)
{
TDLinkList* sList = (TDLinkList*)list;
DLinkListNode* ret = NULL;
if (sList != NULL)
{
sList->slider = sList->header.next;
ret = sList->slider;
}
return ret;
}
DLinkListNode* DLinkList_Current(DLinkList* list)
{
TDLinkList* sList = (TDLinkList*)list;
DLinkListNode* ret = NULL;
if (sList != NULL)
{
ret = sList->slider;
}
return ret;
}
DLinkListNode* DLinkList_Next(DLinkList* list)
{
TDLinkList* sList = (TDLinkList*)list;
DLinkListNode* ret = NULL;
if (sList != NULL && sList->slider != NULL)
{
ret = sList->slider;
sList->slider = ret->next;
}
return ret;
}
DLinkListNode* DLinkList_Pre(DLinkList* list)
{
TDLinkList* sList = (TDLinkList*)list;
DLinkListNode* ret = NULL;
if (sList != NULL && sList->slider != NULL)
{
ret = sList->slider;
sList->slider = ret->pre;
}
return ret;
}
main.c文件
#include "dlinklist.h"
struct Value
{
DLinkListNode circlenode;
int v;
};
int main()
{
int i = 0;
struct Value* pv;
DLinkList* list = DLinkList_Create();
struct Value v1, v2, v3, v4, v5;
v1.v = 1;
v2.v = 2;
v3.v = 3;
v4.v = 4;
v5.v = 5;
DLinkList_Insert(list, (DLinkListNode*)&v1, DLinkList_Length(list));
DLinkList_Insert(list, (DLinkListNode*)&v2, DLinkList_Length(list));
DLinkList_Insert(list, (DLinkListNode*)&v3, DLinkList_Length(list));
DLinkList_Insert(list, (DLinkListNode*)&v4, DLinkList_Length(list));
DLinkList_Insert(list, (DLinkListNode*)&v5, DLinkList_Length(list));
for (i = 0; i < DLinkList_Length(list); i++)
{
pv = (struct Value*)DLinkList_Get(list, i);
printf("%d\n", pv->v);
}
printf("\n");
DLinkList_Delete(list, DLinkList_Length(list) - 1);
DLinkList_Delete(list, 0);
for (i = 0; i < DLinkList_Length(list); i++)
{
pv = (struct Value*)DLinkList_Next(list);
printf("%d\n", pv->v);
}
printf("\n");
DLinkList_Reset(list);
DLinkList_Next(list);
pv = (struct Value*)DLinkList_Current(list);
printf("%d\n", pv->v);
pv = (struct Value*)DLinkList_DeleteNode(list,(DLinkListNode*)pv);
pv = (struct Value*)DLinkList_Current(list);
printf("%d\n", pv->v);
DLinkList_Pre(list);
pv = (struct Value*)DLinkList_Current(list);
printf("%d\n", pv->v);
printf("Length:%d\n", DLinkList_Length(list));
DLinkList_Destroy(list);
system("pause");
return 0;
}
上一篇: pandas统计重复值次数的方法实现
下一篇: 五花肉是三线肉吗?怎么挑选比较好?