双向链表

一、单链表的局限性
              1.单链表的结点都只有一个指向下一个结点的指针。
                    2.单链表的数据元素无法直接访问其前驱的元素
二、双向链表的定义
            在链表的指针中增加一个指向其前驱的pre指针
          
三、双向链表的操作
      1.插入操作
                                                                              

  
  
current -> next = node ;
node->next=next;
next->pre=node;
node->pre=curent;
      2.删除操作
                                                                
  
  
current->next=next;
next->pre=current;
    四 、双向链表的新操作
      1.获取当前游标指向的数据元素
       2.将游标重置指向链表的第一个元素
      3.将游标移动指向到链表中的下一个元素
      4.将游标移动指向到链表中的上一个元素
      5.直接指定删除链表中的某个数据元素          
  
  
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.h
   
   
#ifndef _DLINKLIST_H_
#define _DLINKLIST_H_
 
typedef void DLinkList;
 
typedef struct _tag_DLinkListNode DLinkListNode;
struct _tag_DLinkListNode
{
DLinkListNode* next;
DLinkListNode* pre;
};
 
DLinkList* DLinkList_Creat();
 
void DLinkList_Destory(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);
 
#endif
DlinkList.c
   
   
#include<stdio.h>
#include<malloc.h>
#include"DLinkList.h"
 
/*双向链表的头结点的结构*/
typedef struct _tag_DLinkList
{
DLinkListNode header;
DLinkListNode* slider;
int length;
 
}TDlinkList;
 
/*创建一个双向链表*/
DLinkList* DLinkList_Creat()
{
TDlinkList* ret = (TDlinkList*)malloc(sizeof(TDlinkList));
if (ret != NULL)
{
ret->length = 0;
ret->header.next = NULL;
ret->header.pre = NULL;
ret->slider = NULL;
}
return ret;
}
/*销毁创建的双向链表*/
void DLinkList_Destory(DLinkList* list)
{
free(list);
}
/*清空创建的双向链表*/
void DLinkList_Clear(DLinkList* list)
{
TDlinkList* slist = (TDlinkList*)list;
if (slist != NULL)
{
slist->length = 0;
slist->header.next = NULL;
slist->header.pre = NULL;
slist->slider = NULL;
}
}
 
int DLinkList_Length(DLinkList* list)
{
TDlinkList* slist = (TDlinkList*)list;
int ret = -1;
if (slist != NULL)
{
ret = slist->length;
}
return ret;
}
/*向双向链表中插入一个元素*/ //O(n)
 
int DLinkList_Insert(DLinkList*list, DLinkListNode* node, int pos)
{
TDlinkList* slist = (TDlinkList*)list;
int i = 0;
int ret = (list != NULL) && (node != NULL) && (pos >=0);
if (ret)
{
DLinkListNode* current = (DLinkListNode*)list;
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)
{
node->pre = NULL;
slist->slider = node;
}
slist->length++;
}
 
return ret;
 
}
/**从双向链表中取出一个元素*/
DLinkListNode* DLinkList_Get(DLinkList* list, int pos)
{
TDlinkList* slist = (TDlinkList*)list;
DLinkListNode* ret=NULL;
int i = 0;
if ((slist != NULL) && (pos >= 0) && (pos < slist->length))
{
DLinkListNode* current = (DLinkListNode*)slist;
for (i = 0; i < pos; i++)
{
current = current->next;
}
ret = current->next;
}
return ret;
 
}
 
/*删除双向链表中的一个元素*/
DLinkListNode* DLinkList_Delete(DLinkList* list, int pos)
{
TDlinkList* slist = (TDlinkList*)list;
DLinkListNode* ret = NULL;
int i = 0;
if ((slist != NULL) && (pos >= 0) && (pos <= slist->length))
{
/*current指向表头*/
DLinkListNode* current = (DLinkListNode*)slist;
DLinkListNode* next=NULL;
/*找到要背删除的元素*/
for (i = 0; i < pos; i++)
{
current = current->next;
}
ret = current->next;
next = ret->next;
 
current->next = next;
if (next != NULL)
{
next->pre = current;
/*被删的元素为第一个*/
if (current == (DLinkListNode*)slist)
{
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 = (DLinkListNode*)slist;
for (i = 0; i < slist->length; i++)
{
if (current->next == node)
{
ret = current->next;
break;
}
current = current->next;
}
if (ret != NULL)
{
DLinkList_Delete(slist,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<stdio.h>
#include"Dlinklist.h"
 
struct Value
{
DLinkListNode header;
int v;
 
};
int main()
{
int i = 0;
DLinkList* list = DLinkList_Creat();
struct Value v1;
struct Value v2;
struct Value v3;
struct Value v4;
struct Value v5;
struct Value* pv;
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);
printf("\n");
DLinkList_DeleteNode(list,(DLinkListNode*)pv);
pv = (struct Value*)DLinkList_current(list);
printf("%d\n", pv->v);
 
printf("\n");
DLinkList_Pre(list);
 
pv = (struct Value*)DLinkList_current(list);
printf("%d\n", pv->v);
DLinkList_Destory(list);
return 0;
}

六、双向链表的优势
       1.双向链表在单链表的基础上增加了指向前驱的指针
       2.功能上双向链表可以完全取代单链表
      3.循环链表的Next ,Pre和Current可以高效的遍历链表中所有的元素

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值