【整理】有序单链表的去重
有序单链表的去重
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("申请内存空间失败\n"); 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("\n"); 276 277 //单链表的创建二:尾插法建立单链表 278 printf("请输入单链表的数据:"); 279 list = LinkedListCreatT(); 280 for (start = list->next; start != NULL; start = start->next) 281 printf("%d", start->data); 282 printf("\n"); 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("\n"); 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("\n"); 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("\n"); 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("\n"); 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("\n"); 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("\n"); 334 335 rhead=DeleteDuplicates_3(list);//如果不存在哨兵结点 336 for (start = rhead; start != NULL; start = start->next) 337 printf("%d", start->data); 338 printf("\n"); 339 340 system("pause"); 341 return 0; 342 } 343 //注意:结束输入的时候连续输入三个ctrl+z