Loading

单向循环链表

 

 

注意:

           在插入和删除的操作中,一定要把链表的头和尾拿出来单独分析!  由于链表在第一次完整连接后(比如下面程序中的PushBack函数)每个节点在链表中的内存地址已经固定了下来,比如上图中,b里保存的指针始终就是指向c的next的地址,c中保存的指针始终就是指向d的next的地址,d中保存的指针始终是指向head的地址,所以即使在a,b间插入一个元素e,也不会影响b,c,d节点指针的指向。所以只要不是有关处理头尾元素的操作,都不需要从头到尾地把链表重新连接一遍!因为位置在第一次连接的时候就已经固定了!

 

 1 //CircleList.h
 2 
 3 #pragma once
 4 
 5 #include <stdio.h>
 6 #include <stdlib.h>
 7 
 8 typedef struct Node
 9 {
10     int element;
11     Node *next;
12 }Node;
13 
14 typedef struct CircleList    //单向循环链表
15 {
16     Node *head;
17     int length;
18 }CircleList;
19 
20 void InitList(CircleList *cir);    //创建循环链表
21 
22 Node* GetPrev(CircleList *cir, Node* q);  //获取节点q前驱元素的指针
23 
24 Node* GetBack(CircleList *cir, Node* q);  //获取节点q后继元素的指针
25 
26 Node* BackElem(CircleList *cir);  //返回指向尾节点的指针
27 
28 void PushBack(CircleList *cir, int elem);  //向链表尾部添加元素
29 
30 void InsertElem(CircleList *cir, int position, int elem); //在position的前一个位置处插入元素
31 
32 void DeleteElem(CircleList *cir, int position);  //删除position位置处的元素
33 
34 void ClearList(CircleList *cir);   //清空循环链表
35 
36 void PrintListFromFirst(CircleList *cir);   //从第一个元素开始遍历循环链表
37 
38 void PrintListFromPosition(CircleList *cir, int position);  //从第position处的元素开始循环遍历整个链表

 

  1 //CircleList.c
  2 
  3 #include <stdio.h>
  4 #include <stdlib.h>
  5 #include "CircleList.h"
  6 
  7 void InitList(CircleList *cir)    //创建循环链表
  8 {
  9     cir->length = 0;
 10     cir->head = (Node*)malloc(sizeof(Node));
 11     cir->head->next = NULL;
 12 }
 13 
 14 Node* GetPrev(CircleList *cir, Node* q)  //获取节点q前驱元素的指针
 15 {
 16     if (cir->head->next == q)
 17     {
 18         printf("该节点没有前驱元素!\n");
 19         return NULL;
 20     }
 21     Node *p = cir->head;
 22     for (int i = 1; i <= cir->length; ++i)
 23     {
 24         p = p->next;
 25         if (p->next == q)
 26             return p;
 27     }
 28 }
 29 
 30 Node* GetBack(CircleList *cir, Node* q)  //获取节点q后继元素的指针
 31 {
 32     if (q == BackElem(cir))
 33     {
 34         printf("该节点没有后继元素!\n");
 35         return NULL;
 36     }
 37     Node *p = cir->head;
 38     for (int i = 1; i <= cir->length; ++i)
 39     {
 40         p = p->next;
 41         if (q->next == p)
 42             return p;
 43     }
 44 }
 45 
 46 Node* BackElem(CircleList *cir)  //返回指向尾节点的指针
 47 {
 48     Node *p = cir->head;
 49     if (cir->length == 0)
 50         return p;
 51     for (int i = 1; i <= cir->length; ++i)
 52         p = p->next;
 53     return p;
 54 }
 55 
 56 void PushBack(CircleList *cir, int elem)   //向链表尾部添加元素
 57 {
 58     Node *NewNode = (Node*)malloc(sizeof(Node));
 59     NewNode->element = elem;
 60     Node *p = BackElem(cir);
 61     p->next = NewNode;
 62     NewNode->next = cir->head->next;
 63     ++cir->length;
 64 }
 65 
 66 void InsertElem(CircleList *cir, int position, int elem) //在position的前一个位置处插入元素(head的position为0)
 67 {
 68     if (position > cir->length + 1 || position < 1)
 69     {
 70         printf("插入失败!请在合理的范围内插入元素!\n");
 71         return;
 72     }
 73     if (position == cir->length + 1 || position == 1)
 74     {
 75         Node *q = BackElem(cir);
 76         Node *NewNode = (Node*)malloc(sizeof(Node));
 77         NewNode->element = elem;
 78         q->next = NewNode;
 79         NewNode->next = cir->head->next;
 80         if (position == 1)
 81             cir->head->next = NewNode;
 82         ++cir->length;
 83         return;
 84     }
 85     Node *p = cir->head;
 86     for (int i = 1; i <= position - 1; ++i)
 87         p = p->next;   //获取position前一个位置处的指针p
 88     Node *NewNode = (Node*)malloc(sizeof(Node));
 89     NewNode->element = elem;
 90     NewNode->next = p->next;
 91     p->next = NewNode;
 92     ++cir->length;
 93     return;
 94 }
 95 
 96 
 97 void DeleteElem(CircleList *cir, int position)  //删除position位置处的元素
 98 {
 99     Node *p = cir->head;
100     if (position == 1)
101     {
102         p = p->next;
103         cir->head->next = p->next;
104         Node *q = BackElem(cir);
105         q->next = p->next;
106         free(p);
107         --cir->length;
108         return;
109     }
110     if (position == cir->length)
111     {
112         Node *q = BackElem(cir);
113         Node *p = GetPrev(cir, q);         //令p指向倒数第二个元素
114         p->next = cir->head->next;
115         free(q);
116         --cir->length;
117         return;
118     }
119     for (int i = 1; i <= position - 1; ++i)
120         p = p->next;   //获取position前一个位置处的指针p
121     Node *q = p->next;
122     p->next = q->next;
123     free(q);
124     --cir->length;
125     return;
126 }
127 
128 
129 void ClearList(CircleList *cir)   //清空循环链表
130 {
131     int temp = cir->length;  //删除过程中cir->length时刻变化,所以应该先将其原始值保存下来
132     for (int i = 1; i <= temp; ++i)
133     {
134         DeleteElem(cir, 1);        //删除temp次1号节点,即可把整个链表清空
135     }                                //删除过程中length已经在一直自减,所以不需要添加额外的length自减语句
136 }
137 
138 void PrintListFromFirst(CircleList *cir)   //从第一个元素开始遍历循环链表
139 {
140     Node *p = cir->head;
141     for (int i = 1; i <= cir->length; ++i)
142     {
143         p = p->next;
144         printf("%d  ", p->element);
145     }
146 }
147 
148 void PrintListFromPosition(CircleList *cir, int position)  //从第position处的元素开始循环遍历整个链表
149 {
150     Node *p = cir->head;
151     for (int i = 1; i <= position; ++i)
152         p = p->next;   //获取position位置处的指针p
153 
154     Node *org = p;     //用org记录p的原始位置,用于作为循环遍历的终止条件
155     do
156     {
157         printf("%d ", p->element);
158         p = p->next;
159     } while (p != org);
160 }

 

 

 

 1 //main.c
 2 
 3 #include <stdio.h>
 4 #include <stdlib.h>
 5 #include "CircleList.h"
 6 
 7 int main()
 8 {
 9     CircleList cir;
10     InitList(&cir);
11     PushBack(&cir, 1);
12     PushBack(&cir, 2);
13     PushBack(&cir, 3);
14     PushBack(&cir, 4);
15     PushBack(&cir, 5);
16     PushBack(&cir, 6);
17     PushBack(&cir, 7);
18     PushBack(&cir, 8);
19     InsertElem(&cir,5,777);
20 
21 //  ClearList(&cir);
22 //  InsertElem(&cir, 5, 666);
23 //  DeleteElem(&cir,8);
24     Node *p = cir.head -> next;
25 //  Node* p =BackElem(&cir);
26     printf("%d\n", p->element);
27     Node *q = GetBack(&cir, p);
28     printf("%d\n", q->element);
29     Node *q2 = GetPrev(&cir, q);
30     printf("%d\n", q2->element);
31 //  DeleteElem(&cir,7);
32 //  PrintListFromFirst(&cir);
33 //  PrintListFromPosition(&cir,8);
34 //  printf("%d", cir.length);
35 
36     return 0;
37 }

 

posted @ 2018-09-30 09:06  拾月凄辰  阅读(242)  评论(0编辑  收藏  举报