【整理】有序单链表的去重

有序单链表的去重

  1 #include<stdio.h>
  2 #include<stdlib.h>
  3 
  4 typedef int Elemtype;
  5 typedef struct Node
  6 {
  7     Elemtype data;
  8     struct Node *next;
  9 }Node, *LinkedList;
 10 
 11 //单链表的初始化
 12 LinkedList LinkedListInit()
 13 {
 14     Node *L;
 15     L = (Node*)malloc(sizeof(Node));
 16     if (L == NULL)
 17     {
 18         printf("申请内存空间失败
");
 19     }
 20     L->next = NULL;
 21     return L;
 22 }
 23 
 24 //单链表的创建一:头插法建立单链表
 25 LinkedList LinkedListCreatH()
 26 {
 27     Node *L;
 28     L = (Node *)malloc(sizeof(Node));
 29     L->next = NULL;
 30 
 31     Elemtype x;
 32     while (scanf("%d", &x) != EOF)
 33     {
 34         Node *p;
 35         p = (Node *)malloc(sizeof(Node));
 36         p->data = x;
 37         p->next = L->next;
 38         L->next = p;
 39     }
 40     return L;
 41 }
 42 
 43 //单链表的创建二:尾插法建立单链表
 44 LinkedList LinkedListCreatT()
 45 {
 46     Node *L;
 47     L = (Node *)malloc(sizeof(Node));
 48     L->next = NULL;
 49     Node *r;
 50     r = L;
 51     Elemtype x;
 52     while (scanf("%d", &x) != EOF)
 53     {
 54         Node *p;
 55         p = (Node *)malloc(sizeof(Node));
 56         p->data = x;
 57         //p->next = NULL;
 58         r->next = p;
 59         r = p;
 60     }
 61     r->next = NULL;
 62     return L;
 63 }
 64 
 65 //单链表的插入,在链表的第i个位置插入x的元素
 66 //要在第i个位置插入,就得先找到第(i-1)个位置,插在它后面
 67 LinkedList LinkedListInsert(LinkedList L, int i, Elemtype x)
 68 {
 69     Node *pre;
 70     pre = L;
 71     int tempi = 0;
 72     for (tempi = 1; tempi < i; tempi++)
 73         pre = pre->next;
 74     Node *p;
 75     p = (Node *)malloc(sizeof(Node));
 76     p->data = x;
 77     p->next = pre->next;
 78     pre->next = p;
 79     return L;
 80 }
 81 
 82 //单链表的删除,在链表中删除第一个值为x的元素
 83 LinkedList LinkedListDelete(LinkedList L, Elemtype x)
 84 {
 85     Node *pre, *p;
 86     p = L->next;
 87     while (p->data != x)
 88     {
 89         pre = p;
 90         p = p->next;
 91     }
 92     pre->next = p->next;
 93     free(p);
 94     return L;
 95 }
 96 
 97 //单链表的反转
 98 LinkedList LinkedListReverse(LinkedList L)
 99 {
100 
101     Node *rhead = NULL;
102     Node *prev = NULL;
103     Node *p = L->next;//如果原链表的头是一个结点,结点的内容为任意值,p要指向头的下一个结点才是链表的第一个值
104                       //Node *p = L;//如果原链表的头是一个指针,p直接等于Lj就可以了,L指的就是链表的第一个值
105     Node *pnext = NULL;
106     while (p != NULL)
107     {
108         pnext = p->next;
109         if (pnext == NULL)
110             rhead = p;
111         p->next = prev;
112         prev = p;
113         p = pnext;
114     }
115     free(L);
116     return rhead;
117 }
118 
119 //有序单链表的去重一
120 //输入1->2->2->3,输出1->2->3
121 LinkedList DeleteDuplicates_1(LinkedList L)
122 {
123     if (L == NULL || L->next == NULL||L->next->next==NULL)
124         return L;
125     //if (L == NULL || L->next == NULL)//如果不存在哨兵结点
126     //    return L;
127     Node *pre;
128     Node *p;
129     Node *pnext;
130     pre = L->next;//因为第一个结点L是哨兵结点,所以指向L的下一个结点
131     p = L->next->next;
132     //pre = L;//如果不存在哨兵结点
133     //p = L->next;
134     while (p != NULL)
135     {
136         pnext = p->next;
137         if (pre->data == p->data)
138         { 
139             pre->next = pnext;
140             free(p);
141         }
142         else
143             pre = p;
144         p = pnext;
145     }
146     return L;
147 }
148 
149 //有序单链表的去重二
150 //输入1->2->2->3,输出1->3
151 //输入1->1->2->3,输出2->3
152 LinkedList DeleteDuplicates_2(LinkedList L)//如果存在哨兵结点
153 {
154     if (L == NULL || L->next == NULL || L->next->next == NULL)
155         return L;
156     Node *prere;
157     Node *pre;
158     Node *p;
159     Node *pnext;
160     int flag = 0;
161     prere = L;
162     pre = L->next;//因为第一个结点是哨兵结点
163     p = L->next->next;
164     //pre = L;//如果不存在哨兵结点
165     //p = L->next;
166     while (p != NULL)
167     {
168         pnext = p->next;
169         if (pre->data == p->data)
170         {
171             pre->next = pnext;
172             free(p);
173             flag = 1;
174         }
175         else
176         {
177             if (flag == 1)
178             {
179                 prere->next = p;
180                 free(pre);
181                 pre = p;
182                 flag = 0;
183             }
184             else
185             {
186                 prere = pre;
187                 pre = p;
188             }
189         }
190         p = pnext;
191     }
192     return L;
193 }
194 
195 LinkedList DeleteDuplicates_3(LinkedList L)//如果不存在哨兵结点
196 {
197     if (L == NULL || L->next == NULL)
198         return L;
199     Node *prere;
200     Node *pre;
201     Node *p;
202     Node *pnext;
203     int flag = 0;
204     pre = L;//如果不存在哨兵结点
205     prere = L;
206     prere--;
207     p = L->next;
208     while (p != NULL)
209     {
210         pnext = p->next;
211         if (pre->data == p->data)
212         {
213             pre->next = pnext;
214             free(p);
215             flag = 1;
216         }
217         else
218         {
219             if (flag == 1)
220             {
221                 if (pre == L)
222                 {
223                     L = p;
224                     free(pre);
225                     pre = p;
226                     prere = p;
227                     prere--;
228                 }
229                 else
230                 {
231                     prere->next = p;
232                     free(pre);
233                     pre = p;
234                 }
235                 flag = 0;
236             }
237             else
238             {
239                 prere = pre;
240                 pre = p;
241             }
242         }
243         p = pnext;
244     }
245     if (flag == 1)
246     {
247         if (pre == L)
248         {
249             L = p;
250             free(pre);
251             pre = p;
252             prere = p;
253             prere--;
254         }
255         else
256         {
257             prere->next = p;
258             free(pre);
259             pre = p;
260         }
261         flag = 0;
262     }
263     return L;
264 }
265 
266 int main()
267 {
268     LinkedList list, start;
269     
270     //单链表的创建一:头插法建立单链表
271     printf("请输入单链表的数据:");
272     list = LinkedListCreatH();
273     for (start = list->next; start != NULL; start = start->next)
274         printf("%d", start->data);
275     printf("
");
276     
277     //单链表的创建二:尾插法建立单链表
278     printf("请输入单链表的数据:");
279     list = LinkedListCreatT();
280     for (start = list->next; start != NULL; start = start->next)
281         printf("%d", start->data);
282     printf("
");
283     
284     //单链表的插入,在链表的第i个位置插入x的元素
285     int i, x;
286     printf("请输入插入数据的位置:");
287     scanf("%d", &i);
288     printf("请输入插入数据的值:");
289     scanf("%d", &x);
290     LinkedListInsert(list, i, x);
291     for (start = list->next; start != NULL; start = start->next)
292         printf("%d", start->data);
293     printf("
");
294 
295     //单链表的删除,在链表中删除第一个值为x的元素
296     printf("请输入要删除的元素的值:");
297     scanf("%d", &x);
298     LinkedListDelete(list, x);
299     for (start = list->next; start != NULL; start = start->next)
300         printf("%d", start->data);
301     printf("
");
302 
303     //单链表的反转
304     LinkedList rhead;
305     rhead = LinkedListReverse(list);
306     for (start = rhead; start != NULL; start = start->next)
307         printf("%d", start->data);
308     printf("
");
309     
310 
311     /*************************************************************/
312     //单链表的创建二:尾插法建立单链表
313     printf("请输入单链表的数据:");
314     list = LinkedListCreatT();
315     for (start = list->next; start != NULL; start = start->next)
316         printf("%d", start->data);
317     printf("
");
318     
319     //有序单链表的去重一
320     //输入1->2->2->3,输出1->2->3
321     DeleteDuplicates_1(list);
322     for (start = list->next; start != NULL; start = start->next)
323         printf("%d", start->data);
324     printf("
");
325     
326 
327     //有序单链表的去重二
328     //输入1->2->2->3,输出1->3
329     //输入1->1->2->3,输出2->3
330     DeleteDuplicates_2(list);//如果存在哨兵结点
331     for (start = list->next; start != NULL; start = start->next)
332         printf("%d", start->data);
333     printf("
");
334     
335     rhead=DeleteDuplicates_3(list);//如果不存在哨兵结点
336     for (start = rhead; start != NULL; start = start->next)
337         printf("%d", start->data);
338     printf("
");
339 
340     system("pause");
341     return 0;
342 }
343 //注意:结束输入的时候连续输入三个ctrl+z
原文地址:https://www.cnblogs.com/engraver-lxw/p/7631970.html