今天介绍两个链表的简单应用。
1.约瑟夫问题
假设有N个人决定选出一个领导人,方法如下:所有人排成一个圆圈,按顺序数数,每次数到第M个人出局,此时,他两边的人靠拢重新形成圆圈。问题是找出哪一个人将会是最后剩下的那个人。下列程序依次读入N和M,并给出最终结果。
#include <stdlib.h> #include <stdio.h> typedef struct node* link; struct node { int item; link next; }; int main(int argc,char *argv[]) { int i,N = atoi(argv[1]),M = atoi(argv[2]); link t = malloc(sizeof *t),x = t; t->item = 1; t->next = t; for (i = 2;i <= N;i++) { x = (x->next = malloc(sizeof *x)); x->item = i; x->next = t; } while (x != x->next) { for (i = 1;i < M;i++) x = x->next; x->next = x->next->next; N--; } printf("%d\n",x->item); }
2.插入排序
前面介绍过插入排序,是用数组的方法实现的,程序很简单,用链表反而显得比较复杂。但是主要是为了熟悉链表的使用。
#include <stdlib.h> #include <stdio.h> typedef struct node* link; struct node { int item; link next; }; int main(int argc,char *argv[]) { int i,N = atoi(argv[1]); struct node heada,headb; link t,x,a,b,u; t = &heada; a = t; for (i = 0;i < N;i++) { t->next = malloc(sizeof *t); t->next->item = rand() % 100; t = t->next; t->next = NULL; } for (t = a;t->next != NULL;t = t->next) printf("%d ",t->next->item); printf("\n"); for (b = &headb,b->next = NULL,t = a->next;t != NULL;t = u) { u = t->next; for (x = b;x->next != NULL;x = x->next) if(t->item < x->next->item) break; //x->next = t; //x->next->next = NULL; t->next = x->next; x->next = t; } for (t = b;t->next != NULL;t = t->next) printf("%d ",t->next->item); printf("\n"); }
上面两个例子有个很明显的问题,只是动态申请了内存,但是没有释放,实际写程序的时候千万要注意释放,这里偷个懒就没加了。
对于第二个例子,在每次插入的时候都是从链表头到尾遍历,可以考虑利用双向链表或者循环双向链表实现从链表尾到头的遍历。
时间: 2024-10-19 17:54:38