23.双向环形链表

运行截图:

  • 结点结构体
    1 typedef struct LinkNode
    2 {
    3     int data;
    4     struct LinkNode *pPre;
    5     struct LinkNode *pNext;
    6 }node,*PNODE;

     

  • 创建一个结构体保存头部和尾部
    typedef struct info
    {
        node *head;//指向头部
        node *tail;//指向尾部
    }DList;

     

  • 初始化环形链表
    1 void init(DList *p)
    2 {
    3     p->head = NULL;
    4     p->tail = NULL;
    5 }

     

  •  1 //在链表尾部插入数据
     2 void addDataBack(DList *p, int data)
     3 {
     4     //创建一个新的结点
     5     node *pnew = (node *)malloc(sizeof(node));
     6     pnew->data = data;
     7     pnew->pNext = NULL;
     8     pnew->pPre = NULL;
     9 
    10     //如果链表为空
    11     if (p->head == NULL || p->tail == NULL)
    12     {
    13         //插入一个结点
    14         p->tail = p->head = pnew;
    15         pnew->pPre = pnew->pNext = pnew;
    16     }
    17     //如果只有一个结点
    18     else if(p->head == p->tail)
    19     {
    20         p->head->pPre = pnew;
    21         p->head->pNext = pnew;
    22 
    23         pnew->pPre = p->head;
    24         pnew->pNext = p->head;
    25 
    26         p->tail = pnew;//保存尾部
    27     }
    28     //如果大于一个结点
    29     else
    30     {
    31         pnew->pPre = p->tail;
    32         pnew->pNext = p->head;
    33 
    34         p->tail->pNext = pnew;
    35         p->head->pPre = pnew;
    36 
    37         p->tail = pnew;
    38     }
    39 }

     

  • 在链表头部插入数据
     1 void addDataHead(DList *p, int data)
     2 {
     3     //创建一个新的结点
     4     PNODE pnew = (PNODE)malloc(sizeof(node));
     5     pnew->data = data;
     6     pnew->pNext = NULL;
     7     pnew->pPre = NULL;
     8 
     9     //如果链表为空
    10     if (p->head == NULL && p->tail == NULL)
    11     {
    12         p->tail = p->head = pnew;
    13         pnew->pPre = pnew->pNext = pnew;
    14     }
    15     //如果只有一个结点
    16     else if (p->head == p->tail)
    17     {
    18         pnew->pPre = pnew->pNext = p->head;
    19         p->head->pNext = p->head->pPre = pnew;
    20 
    21         p->head = pnew;
    22     }
    23     //如果大于一个结点
    24     else
    25     {
    26         pnew->pPre = p->tail;
    27         pnew->pNext = p->head;
    28 
    29         p->head->pPre = pnew;
    30         p->tail->pNext = pnew;
    31 
    32         p->head = pnew;
    33     }
    34 }

     

  • 查询数据
     1 //查询数据
     2 PNODE find(DList *p, int data)
     3 {
     4     if (p->head == NULL || p->tail == NULL)
     5     {
     6         return NULL;
     7     }
     8     else if (p->head == p->tail)
     9     {
    10         PNODE pl = p->head;
    11         if (pl->data == data)
    12         {
    13             return pl;
    14         }
    15         else
    16         {
    17             return NULL;
    18         }
    19     }
    20     else
    21     {
    22         PNODE pl = p->head;
    23         for (; pl->pNext != p->head; pl = pl->pNext)
    24         {
    25             if (pl->data == data)
    26             {
    27                 return pl;
    28             }
    29         }
    30         //尾部补充一个
    31         if (pl->data == data)
    32         {
    33             return pl;
    34         }
    35         else
    36         {
    37             return NULL;
    38         }
    39     }
    40 }

     

  • 改变一个结点的数据
    void change(DList *p, int data,int newdata)
    {
        if (p->head == NULL || p->tail == NULL)
        {
            return;
        }
        //如果只有一个结点
        else if (p->head == p->tail)
        {
            PNODE pl = p->head;
            if (pl->data == data)
            {
                pl->data == newdata;
            }
        }
        //如果大于一个结点
        else
        {
            PNODE pl = p->head;
            for (; pl->pNext != p->head; pl = pl->pNext)
            {
                if (pl->data == data)
                {
                    pl->data == newdata;
                }
            }
            //尾部补充一个
            if (pl->data == data)
            {
                pl->data == newdata;
            }
        }
    }

     

  • 删除一个结点
     1 void deleteData(DList *p, int data)
     2 {
     3     //先判断只有一个结点的情况
     4     if (p->head == p->tail)
     5     {
     6         if (p->head->data == data)
     7         {
     8             free(p->head);
     9             p->head = NULL;
    10             p->tail = NULL;
    11         }
    12     }
    13     //结点个数大于1
    14     else
    15     {
    16         //备份头结点
    17         PNODE pl = p->head;
    18         //先判断是不是头结点
    19         if (pl->data == data)
    20         {
    21             pl->pNext->pPre = p->tail;
    22             p->tail->pNext = pl->pNext;
    23             p->head = pl->pNext;
    24             free(pl);
    25         }
    26         //如果不是头结点
    27         else
    28         {
    29             //一直从后一个遍历到结束
    30             pl = pl->pNext;
    31             while (pl != p->head)
    32             {
    33                 if (pl->data == data)
    34                 {
    35                     break;
    36                 }
    37                 else
    38                 {
    39                     pl = pl->pNext;
    40                 }
    41             }
    42             //如果找到了
    43             if (pl != p->head)
    44             {
    45                 //如果循环到尾部
    46                 if (pl == p->tail)
    47                 {
    48                     pl->pPre->pNext = p->head;
    49                     p->head->pPre = pl->pPre;
    50 
    51                     p->tail = pl->pPre;
    52                     free(pl);
    53                 }
    54                 //如果在中间
    55                 else
    56                 {
    57                     pl->pNext->pPre = pl->pPre;
    58                     pl->pPre->pNext = pl->pNext;
    59                     free(pl);
    60                 }
    61             }
    62         }
    63     }
    64     
    65 }

     

完整代码:

  1 #include <stdio.h>
  2 #include <stdlib.h>
  3 
  4 //双链表节点
  5 typedef struct LinkNode
  6 {
  7     int data;
  8     struct LinkNode *pPre;
  9     struct LinkNode *pNext;
 10 }node,*PNODE;
 11 
 12 //创建一个结构体保存头部和尾部
 13 typedef struct info
 14 {
 15     node *head;//指向头部
 16     node *tail;//指向尾部
 17 }DList;
 18 
 19 void init(DList *p)
 20 {
 21     p->head = NULL;
 22     p->tail = NULL;
 23 }
 24 
 25 //在链表尾部插入数据
 26 void addDataBack(DList *p, int data)
 27 {
 28     //创建一个新的结点
 29     node *pnew = (node *)malloc(sizeof(node));
 30     pnew->data = data;
 31     pnew->pNext = NULL;
 32     pnew->pPre = NULL;
 33 
 34     //如果链表为空
 35     if (p->head == NULL || p->tail == NULL)
 36     {
 37         //插入一个结点
 38         p->tail = p->head = pnew;
 39         pnew->pPre = pnew->pNext = pnew;
 40     }
 41     //如果只有一个结点
 42     else if(p->head == p->tail)
 43     {
 44         p->head->pPre = pnew;
 45         p->head->pNext = pnew;
 46 
 47         pnew->pPre = p->head;
 48         pnew->pNext = p->head;
 49 
 50         p->tail = pnew;
 51     }
 52     //如果大于一个结点
 53     else
 54     {
 55         pnew->pPre = p->tail;
 56         pnew->pNext = p->head;
 57 
 58         p->tail->pNext = pnew;
 59         p->head->pPre = pnew;
 60 
 61         p->tail = pnew;
 62     }
 63 }
 64 
 65 //在链表头部插入数据
 66 void addDataHead(DList *p, int data)
 67 {
 68     //创建一个新的结点
 69     PNODE pnew = (PNODE)malloc(sizeof(node));
 70     pnew->data = data;
 71     pnew->pNext = NULL;
 72     pnew->pPre = NULL;
 73 
 74     //如果链表为空
 75     if (p->head == NULL && p->tail == NULL)
 76     {
 77         p->tail = p->head = pnew;
 78         pnew->pPre = pnew->pNext = pnew;
 79     }
 80     //如果只有一个结点
 81     else if (p->head == p->tail)
 82     {
 83         pnew->pPre = pnew->pNext = p->head;
 84         p->head->pNext = p->head->pPre = pnew;
 85 
 86         p->head = pnew;
 87     }
 88     //如果大于一个结点
 89     else
 90     {
 91         pnew->pPre = p->tail;
 92         pnew->pNext = p->head;
 93 
 94         p->head->pPre = pnew;
 95         p->tail->pNext = pnew;
 96 
 97         p->head = pnew;
 98     }
 99 }
100 
101 //查询数据
102 PNODE find(DList *p, int data)
103 {
104     if (p->head == NULL || p->tail == NULL)
105     {
106         return NULL;
107     }
108     else if (p->head == p->tail)
109     {
110         PNODE pl = p->head;
111         if (pl->data == data)
112         {
113             return pl;
114         }
115         else
116         {
117             return NULL;
118         }
119     }
120     else
121     {
122         PNODE pl = p->head;
123         for (; pl->pNext != p->head; pl = pl->pNext)
124         {
125             if (pl->data == data)
126             {
127                 return pl;
128             }
129         }
130         //尾部补充一个
131         if (pl->data == data)
132         {
133             return pl;
134         }
135         else
136         {
137             return NULL;
138         }
139     }
140 }
141 
142 //改变一个结点的数据
143 void change(DList *p, int data,int newdata)
144 {
145     if (p->head == NULL || p->tail == NULL)
146     {
147         return;
148     }
149     //如果只有一个结点
150     else if (p->head == p->tail)
151     {
152         PNODE pl = p->head;
153         if (pl->data == data)
154         {
155             pl->data == newdata;
156         }
157     }
158     //如果大于一个结点
159     else
160     {
161         PNODE pl = p->head;
162         for (; pl->pNext != p->head; pl = pl->pNext)
163         {
164             if (pl->data == data)
165             {
166                 pl->data == newdata;
167             }
168         }
169         //尾部补充一个
170         if (pl->data == data)
171         {
172             pl->data == newdata;
173         }
174     }
175 }
176 
177 //删除一个结点
178 void deleteData(DList *p, int data)
179 {
180     //先判断只有一个结点的情况
181     if (p->head == p->tail)
182     {
183         if (p->head->data == data)
184         {
185             free(p->head);
186             p->head = NULL;
187             p->tail = NULL;
188         }
189     }
190     //结点个数大于1
191     else
192     {
193         //备份头结点
194         PNODE pl = p->head;
195         //先判断是不是头结点
196         if (pl->data == data)
197         {
198             pl->pNext->pPre = p->tail;
199             p->tail->pNext = pl->pNext;
200             p->head = pl->pNext;
201             free(pl);
202         }
203         //如果不是头结点
204         else
205         {
206             //一直从后一个遍历到结束
207             pl = pl->pNext;
208             while (pl != p->head)
209             {
210                 if (pl->data == data)
211                 {
212                     break;
213                 }
214                 else
215                 {
216                     pl = pl->pNext;
217                 }
218             }
219             //如果找到了
220             if (pl != p->head)
221             {
222                 //如果循环到尾部
223                 if (pl == p->tail)
224                 {
225                     pl->pPre->pNext = p->head;
226                     p->head->pPre = pl->pPre;
227 
228                     p->tail = pl->pPre;
229                     free(pl);
230                 }
231                 //如果在中间
232                 else
233                 {
234                     pl->pNext->pPre = pl->pPre;
235                     pl->pPre->pNext = pl->pNext;
236                     free(pl);
237                 }
238             }
239         }
240     }
241     
242 }
243 
244 void insert(DList *p, int data, int newdata)
245 {
246     PNODE pnew = (PNODE)malloc(sizeof(node));//开辟节点
247     pnew->data = newdata;
248     pnew->pNext = NULL;
249     pnew->pPre = NULL;
250 
251     //从头结点开始向后找    
252     PNODE pl = p->head;
253     while (pl->pNext != p->head)
254     {
255         if (pl->data == data)
256         {
257             break;
258         }
259         else
260         {
261             pl = pl->pNext;
262         }
263     }
264     //后面插入
265     //无论最后一个结点是不是要找的结点都插在后面
266     //只有一个结点,插在尾部
267     if (pl == p->head && p->tail == pl)
268     {
269         pnew->pPre = pnew->pNext = p->head;
270         p->head->pNext = p->head->pPre = pnew;
271         p->tail = pnew;
272     }
273     //如果遍历到尾部结点
274     else if (pl == p->tail && pl != p->head)
275     {
276         pnew->pNext = p->head;
277         pnew->pPre = p->tail;
278 
279         p->tail->pNext = pnew;
280         p->head->pPre = pnew;
281 
282         p->tail = pnew;
283     }
284     //如果不在尾结点
285     else
286     {
287         pnew->pPre = pl;
288         pnew->pNext = pl->pNext;
289         
290         pl->pNext->pPre = pnew;
291         pl->pNext = pnew;
292     }
293 }
294 
295 
296 //显示链表的数据
297 void show(DList *p)
298 {
299 
300     if (p->head == NULL || p->tail == NULL)
301     {
302         return;
303     }
304     else if (p->head == p->tail)
305     {
306         PNODE pl = p->head;
307         printf("%d,(CurAddr)%p,(PreAddr)%p,(NextAddr)%p\n", pl->data, pl, pl->pPre, pl->pNext);
308     }
309     else
310     {
311         PNODE pl = p->head;
312         for (; pl->pNext != p->head; pl = pl->pNext)
313         {
314             printf("%d,(CurAddr)%p,(PreAddr)%p,(NextAddr)%p\n", pl->data, pl, pl->pPre, pl->pNext);
315         }
316         //尾部补充一个
317         printf("%d,(CurAddr)%p,(PreAddr)%p,(NextAddr)%p\n", pl->data, pl, pl->pPre, pl->pNext);
318     }
319 }
320 
321 
322 
323 void main()
324 {
325     DList dlist;
326     init(&dlist);
327 
328     for (int i = 0; i < 5; i++)
329     {
330         addDataHead(&dlist,i);
331         //addDataBack(&dlist, i);
332         printf("\n\n");
333         show(&dlist);
334     }
335 
336     //查询数据并修改
337     PNODE px = find(&dlist, 3);
338     px->data = 19;
339     printf("\n\n");
340 
341     //后插数据
342     insert(&dlist, 1, 100);
343     printf("\n\n");
344     show(&dlist);
345 
346     //删除数据
347     deleteData(&dlist, 4);
348     printf("\n\n");
349     show(&dlist);
350     system("pause");
351 }

 

posted @ 2018-02-02 14:39  喵小喵~  阅读(585)  评论(0编辑  收藏  举报