双向链表

单链表的缺陷

1.单链表的结点都只有一个指向下一个结点的指针
2.单链表的数据元素无法直接访问其前驱元,有时单链表会带来访问效率上的问题 

二、双向链表的新操作
 1.获取当前游标指向的数据元素
 2.将游标重置指向链表中的第一个数据元素
 3.将游标移动指向到链表中的下一个数据元素
 4.将游标移动指向到链表中的上一个数据元素
 5.直接指定删除链表中的某个数据元素

  1 #include <stdio.h>
  2 #include <malloc.h>
  3 #include "DLinkList.h"
  4 
  5 typedef struct _tag_DLinkList
  6 {
  7     DLinkListNode header;
  8     DLinkListNode* slider;
  9     int length;
 10 } TDLinkList;
 11 
 12 DLinkList* DLinkList_Create() // O(1)
 13 {
 14     TDLinkList* ret = (TDLinkList*)malloc(sizeof(TDLinkList));
 15     
 16     if( ret != NULL )
 17     {
 18         ret->length = 0;
 19         ret->header.next = NULL;
 20         ret->header.pre = NULL;
 21         ret->slider = NULL;
 22     }
 23     
 24     return ret;
 25 }
 26 
 27 void DLinkList_Destroy(DLinkList* list) // O(1)
 28 {
 29     free(list);
 30 }
 31 
 32 void DLinkList_Clear(DLinkList* list) // O(1)
 33 {
 34     TDLinkList* sList = (TDLinkList*)list;
 35     
 36     if( sList != NULL )
 37     {
 38         sList->length = 0;
 39         sList->header.next = NULL;
 40         sList->header.pre = NULL;
 41         sList->slider = NULL;
 42     }
 43 }
 44 
 45 int DLinkList_Length(DLinkList* list) // O(1)
 46 {
 47     TDLinkList* sList = (TDLinkList*)list;
 48     int ret = -1;
 49     
 50     if( sList != NULL )
 51     {
 52         ret = sList->length;
 53     }
 54     
 55     return ret;
 56 }
 57 
 58 int DLinkList_Insert(DLinkList* list, DLinkListNode* node, int pos) // O(n)
 59 { 
 60     TDLinkList* sList = (TDLinkList*)list;
 61     int ret = (sList != NULL) && (pos >= 0) && (node != NULL);
 62     int i = 0;
 63     
 64     if( ret )
 65     {
 66         DLinkListNode* current = (DLinkListNode*)sList;
 67         DLinkListNode* next = NULL;
 68         
 69         for(i=0; (i<pos) && (current->next != NULL); i++)
 70         {
 71             current = current->next;
 72         }
 73         
 74         next = current->next;
 75         
 76         current->next = node;
 77         node->next = next;
 78         
 79         if( next != NULL )
 80         {
 81             next->pre = node;
 82         }
 83         
 84         node->pre = current;
 85         
 86         if( sList->length == 0 )
 87         {
 88             node->pre = NULL;
 89             sList->slider = node;
 90         }
 91         
 92         sList->length++;
 93     }
 94     
 95     return ret;
 96 }
 97 
 98 DLinkListNode* DLinkList_Get(DLinkList* list, int pos) // O(n)
 99 {
100     TDLinkList* sList = (TDLinkList*)list;
101     DLinkListNode* ret = NULL;
102     int i = 0;
103     
104     if( (sList != NULL) && (0 <= pos) && (pos < sList->length) )
105     {
106         DLinkListNode* current = (DLinkListNode*)sList;
107         
108         for(i=0; i<pos; i++)
109         {
110             current = current->next;
111         }
112         
113         ret = current->next;
114     }
115     
116     return ret;
117 }
118 
119 DLinkListNode* DLinkList_Delete(DLinkList* list, int pos) // O(n)
120 {
121     TDLinkList* sList = (TDLinkList*)list;
122     DLinkListNode* ret = NULL;
123     int i = 0;
124     
125     if( (sList != NULL) && (0 <= pos) && (pos < sList->length) )
126     {
127         DLinkListNode* current = (DLinkListNode*)sList;
128         DLinkListNode* next = NULL;
129         
130         for(i=0; i<pos; i++)
131         {
132             current = current->next;
133         }
134         
135         ret = current->next;
136         next = ret->next;
137         
138         current->next = next;
139         
140         if( next != NULL )
141         {
142             next->pre = current;
143             
144             if( current == (DLinkListNode*)sList )
145             {
146                 next->pre = NULL;
147             }
148         }
149         
150         if( sList->slider == ret )
151         {
152             sList->slider = next;
153         }
154         
155         sList->length--;
156     }
157     
158     return ret;
159 }
160 
161 DLinkListNode* DLinkList_DeleteNode(DLinkList* list, DLinkListNode* node)
162 {
163     TDLinkList* sList = (TDLinkList*)list;
164     DLinkListNode* ret = NULL;
165     int i = 0;
166     
167     if( sList != NULL )
168     {
169         DLinkListNode* current = (DLinkListNode*)sList;
170         
171         for(i=0; i<sList->length; i++)
172         {
173             if( current->next == node )
174             {
175                 ret = current->next;
176                 break;
177             }
178             
179             current = current->next;
180         }
181         
182         if( ret != NULL )
183         {
184             DLinkList_Delete(sList, i);
185         }
186     }
187     
188     return ret;
189 }
190 
191 DLinkListNode* DLinkList_Reset(DLinkList* list)
192 {
193     TDLinkList* sList = (TDLinkList*)list;
194     DLinkListNode* ret = NULL;
195     
196     if( sList != NULL )
197     {
198         sList->slider = sList->header.next;
199         ret = sList->slider;
200     }
201     
202     return ret;
203 }
204 
205 DLinkListNode* DLinkList_Current(DLinkList* list)
206 {
207     TDLinkList* sList = (TDLinkList*)list;
208     DLinkListNode* ret = NULL;
209     
210     if( sList != NULL )
211     {
212         ret = sList->slider;
213     }
214     
215     return ret;
216 }
217 
218 DLinkListNode* DLinkList_Next(DLinkList* list)
219 {
220     TDLinkList* sList = (TDLinkList*)list;
221     DLinkListNode* ret = NULL;
222     
223     if( (sList != NULL) && (sList->slider != NULL) )
224     {
225         ret = sList->slider;
226         sList->slider = ret->next;
227     }
228     
229     return ret;
230 }
231 
232 DLinkListNode* DLinkList_Pre(DLinkList* list)
233 {
234     TDLinkList* sList = (TDLinkList*)list;
235     DLinkListNode* ret = NULL;
236     
237     if( (sList != NULL) && (sList->slider != NULL) )
238     {
239         ret = sList->slider;
240         sList->slider = ret->pre;
241     }
242     
243     return ret;
244 }
 1 #ifndef _DLINKLIST_H_
 2 #define _DLINKLIST_H_
 3 
 4 typedef void DLinkList;
 5 typedef struct _tag_DLinkListNode DLinkListNode;
 6 struct _tag_DLinkListNode
 7 {
 8     DLinkListNode* next;
 9     DLinkListNode* pre;
10 };
11 
12 DLinkList* DLinkList_Create();
13 
14 void DLinkList_Destroy(DLinkList* list);
15 
16 void DLinkList_Clear(DLinkList* list);
17 
18 int DLinkList_Length(DLinkList* list);
19 
20 int DLinkList_Insert(DLinkList* list, DLinkListNode* node, int pos);
21 
22 DLinkListNode* DLinkList_Get(DLinkList* list, int pos);
23 
24 DLinkListNode* DLinkList_Delete(DLinkList* list, int pos);
25 
26 DLinkListNode* DLinkList_DeleteNode(DLinkList* list, DLinkListNode* node);
27 
28 DLinkListNode* DLinkList_Reset(DLinkList* list);
29 
30 DLinkListNode* DLinkList_Current(DLinkList* list);
31 
32 DLinkListNode* DLinkList_Next(DLinkList* list);
33 
34 DLinkListNode* DLinkList_Pre(DLinkList* list);
35 
36 #endif
#include <stdio.h>
#include <stdlib.h>
#include "DLinkList.h"
/* run this program using the console pauser or add your own getch, system("pause") or input loop */

struct Value
{
    DLinkListNode header;
    int v;
};

int main(int argc, char *argv[])
{
    int i = 0;
    DLinkList* list = DLinkList_Create();
    struct Value* pv = NULL;
    struct Value v1;
    struct Value v2;
    struct Value v3;
    struct Value v4;
    struct Value 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
", pv->v);
    }
    
    printf("
");
    
    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
", pv->v);
    }
    
    printf("
");
    
    DLinkList_Reset(list);
    DLinkList_Next(list);
    
    pv = (struct Value*)DLinkList_Current(list);
    
    printf("%d
", pv->v);
    
    DLinkList_DeleteNode(list, (DLinkListNode*)pv);
    
    pv = (struct Value*)DLinkList_Current(list);
    
    printf("%d
", pv->v);
    
    DLinkList_Pre(list);
    
    pv = (struct Value*)DLinkList_Current(list);
    
    printf("%d
", pv->v);
    
    printf("Length: %d
", DLinkList_Length(list));
    
    DLinkList_Destroy(list);
    
    return 0;
}

三、双向链表的当前位置可以访问其前驱和后继,这是它重要的特性,在根本程度上可以完全取代单链表

原文地址:https://www.cnblogs.com/xiaowulang/p/10798041.html