理解双向链表
和单链表类似,单链表是结点只包含了指向下一个结点的后继指针域,而双向链表的结点增加了一个指向前驱的指针域。这样以来方便从某一结点开始,方便访问前一个结点和后一个结点。
双向链表的插入分析
一般插入:
添加辅助指针current和next。
current的后继指针指向插入结点node,node结点的后继指针指向next结点处
next结点的前驱指针指向node结点,node结点的前驱指针指向current结点处
插入头部结点(0号元素):
需要异常处理,辅助指针current指向头部结点,如果current的后继指针指向Null,不作处理,如果current的后继指针不为Null,则辅助指针next为current的后继指针指向得结点,current的前驱指针指向Null。
插入尾部结点:
双向链表的删除分析
普通删除:
删除头结点:
链表中有其他元素
删除0号元素时,应该让next的前驱指针指向Null
只有一个元素
删除尾结点:
//DLinkList.h
#pragma once
typedef void DLinkList;
typedef struct tag_DLinkListNode
{
struct tag_DLinkListNode *next;
struct tag_DLinkListNode *prev;
}TDLinkListNode;
DLinkList* DLinkList_Creat();
void DLinkList_Destroy(DLinkList *list);
void DLinkList_Clear(DLinkList *list);
int DLinkList_GetLength(DLinkList *list);
int DLinkList_Inster(DLinkList *list, TDLinkListNode *node, int pos);
TDLinkListNode *DLinkList_Get(DLinkList *list, int pos);
TDLinkListNode *DLinkList_Delete(DLinkList *list, int pos);
TDLinkListNode *DLinkList_DeleteNode(DLinkList *list, TDLinkListNode *node);
TDLinkListNode *DLinkList_Reset(DLinkList *list);
TDLinkListNode *DLinkList_Current(DLinkList *list);
TDLinkListNode *DLinkList_Next(DLinkList *list);
TDLinkListNode *DLinkList_Prev(DLinkList *list);
//DLinkList .c
#pragma warning(disable : 4996)
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "DLinkList.h"
typedef struct tag_DLinkList
{
TDLinkListNode header;
TDLinkListNode *slider;
int length;
}TDLinkList;
DLinkList *DLinkList_Creat()
{
TDLinkList *list = NULL;
list = (TDLinkList *)malloc(sizeof(TDLinkList));
memset(list, 0, sizeof(TDLinkList));
list->header.next = NULL;
list->header.prev = NULL;
list->slider = NULL;
list->length = 0;
return list;
}
void DLinkList_Destroy(DLinkList * list)
{
TDLinkList *temp = NULL;
if (list == NULL)
{
printf("DLinkList_Destroy err: list = NULL");
return;
}
temp = (TDLinkList *)list;
free(temp);
return;
}
void DLinkList_Clear(DLinkList *list)
{
TDLinkList *temp = NULL;
if (list == NULL)
{
printf("DLinkList_Clear err: list = NULL");
return;
}
temp = (TDLinkList *)list;
temp->length = 0;
temp->header.next = NULL;
temp->header.prev = NULL;
temp->slider = NULL;
return;
}
int DLinkList_GetLength(DLinkList *list)
{
TDLinkList *temp = NULL;
if (list == NULL)
{
printf("DLinkList_GetLength err: list = NULL");
return -1;
}
temp = (TDLinkList *)list;
return temp->length;
}
int DLinkList_Inster(DLinkList *list, TDLinkListNode *node, int pos)
{
TDLinkList *temp = NULL;
if (list == NULL || node == NULL || pos < 0)
{
printf("DLinkList_Inster err: list = NULL || node = NULL || pos < 0");
return -1;
}
temp = (TDLinkList *)list;
if (pos > temp->length)
{
printf("DLinkList_Get err: pos > temp->length");
return -2;
}
TDLinkListNode *current = &(temp->header);
TDLinkListNode *next = NULL;
int i = 0;
for (i = 0; i < pos; i++)
{
current = current->next;
}
//游标指向第一个插进来的节点
if (temp->slider == NULL)
{
temp->slider = node;
}
//插入0号元素时
if (current == &(temp->header))
{
//当插入节点的next = null(异常处理)
if (current->next != NULL)
{
next = current->next;
}
current->prev = NULL;
}
next = current->next;
current->next = node;
node->next = next;
//如果删除尾结点时辅助指针next = null(异常处理)
if (next != NULL)
next->prev = node;
node->prev = current;
temp->length++;
return 0;
}
TDLinkListNode *DLinkList_Get(DLinkList *list, int pos)
{
TDLinkList *temp = NULL;
if (list == NULL || pos < 0)
{
printf("DLinkList_Get err: list = NULL");
return NULL;
}
temp = (TDLinkList *)list;
if (pos > temp->length)
{
printf("DLinkList_Get err: pos > temp->length");
return NULL;
}
TDLinkListNode *current = &(temp->header);
TDLinkListNode *ret = NULL;
int i = 0;
for (i = 0; i < pos; i++)
{
current = current->next;
}
ret = current->next;
return ret;
}
TDLinkListNode *DLinkList_Delete(DLinkList *list, int pos)
{
TDLinkList *temp = NULL;
if (list == NULL || pos < 0)
{
printf("DLinkList_Delete err: list = NULL || node = NULL || pos < 0");
return NULL;
}
temp = (TDLinkList *)list;
if (pos > temp->length)
{
printf("DLinkList_Delete err: pos > temp->length");
return NULL;
}
TDLinkListNode *current = &(temp->header);
TDLinkListNode *next = NULL;
TDLinkListNode *ret = NULL;
int i = 0;
for (i = 0; i < pos; i++)
{
current = current->next;
}
ret = current->next;
next = ret->next;
current->next = next;
if (next != NULL)
{
next->prev = current;
//删除0号元素
if (current == &(temp->header))
{
next->prev = NULL;
}
}
//删除的节点正好是游标所指的节点,那么游标下一
if (temp->slider == ret)
temp->slider = next;
if (temp->length == 0)
{
temp->header.next = NULL;
temp->header.prev = NULL;
temp->slider = NULL;
}
temp->length--;
return ret;
}
TDLinkListNode * DLinkList_DeleteNode(DLinkList *list, TDLinkListNode *node)
{
if (list == NULL || node == NULL)
{
printf("LinkList_DeleteNode err: list = NULL || node = NULL");
return NULL;
}
int i = 0;
TDLinkList *temp = (TDLinkList *)list;
TDLinkListNode *current = &temp->header;
TDLinkListNode *ret = NULL;
for (i = 0; i < temp->length; i++)
{
if (current->next == node)
{
ret = current->next;
break;
}
current = current->next;
}
if (ret != NULL)
{
DLinkList_Delete(temp, i);
}
return ret;
}
TDLinkListNode * DLinkList_Reset(DLinkList * list)
{
TDLinkList *temp = NULL;
if (list == NULL)
{
printf("DLinkList_Reset err: list = NULL");
return NULL;
}
temp = (TDLinkList *)list;
temp->slider = DLinkList_Get(temp, 0);
return temp->slider;
}
TDLinkListNode * DLinkList_Current(DLinkList * list)
{
TDLinkList *temp = NULL;
if (list == NULL)
{
printf("DLinkList_Current err: list = NULL");
return NULL;
}
temp = (TDLinkList *)list;
return temp->slider;
}
TDLinkListNode * DLinkList_Next(DLinkList * list)
{
TDLinkList *temp = NULL;
if (list == NULL)
{
printf("DLinkList_Next err: list = NULL");
return NULL;
}
temp = (TDLinkList *)list;
temp->slider = temp->slider->next;
return temp->slider;
}
TDLinkListNode * DLinkList_Prev(DLinkList * list)
{
TDLinkList *temp = NULL;
if (list == NULL)
{
printf("DLinkList_Prev err: list = NULL");
return NULL;
}
temp = (TDLinkList *)list;
temp->slider = temp->slider->prev;
return temp->slider;
}
//测试代码
#pragma warning(disable : 4996)
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "DLinkList.h"
typedef struct tag_Value
{
TDLinkListNode node;
int val;
}TValue;
int main(int argc, char** argv)
{
DLinkList *list = (DLinkList *)DLinkList_Creat();
if (list == NULL)
{
printf("DLinkList_Creat err: list = NULL");
return -1;
}
TValue v1, v2, v3, v4, v5;
v1.val = 1;
v2.val = 2;
v3.val = 3;
v4.val = 4;
v5.val = 5;
DLinkList_Inster(list, (TDLinkListNode*)&v1, DLinkList_GetLength(list));
DLinkList_Inster(list, (TDLinkListNode*)&v2, DLinkList_GetLength(list));
DLinkList_Inster(list, (TDLinkListNode*)&v3, DLinkList_GetLength(list));
DLinkList_Inster(list, (TDLinkListNode*)&v4, DLinkList_GetLength(list));
DLinkList_Inster(list, (TDLinkListNode*)&v5, DLinkList_GetLength(list));
int i = 0;
for (i = 0; i < DLinkList_GetLength(list); i++)
{
TValue *v = (TValue *)DLinkList_Get(list, i);
printf("val = %d\n", v->val);
}
printf("\n");
DLinkList_Delete(list, 0);
DLinkList_DeleteNode(list, DLinkList_Get(list, DLinkList_GetLength(list) - 1));
printf("%d\n", DLinkList_GetLength(list));
for (i = 0; i < DLinkList_GetLength(list); i++)
{
TValue *v = (TValue *)DLinkList_Get(list, i);
printf("val = %d\n", v->val);
}
printf("\n");
DLinkList_Delete(list, 1);
DLinkList_Reset(list);
DLinkList_Next(list);
TValue *v_1 = (TValue *)DLinkList_Current(list);
printf("val = %d\n", v_1->val);
TValue *v_2 = (TValue *)DLinkList_Prev(list);
printf("val = %d\n", v_2->val);
system("pause");
return 0;
}