算法导论13:双向循环链表 2016.1.13
今天这个又打了很长时间,本来觉得数据结构就是那样,不过是一种思维,但是实际上真正自己打和想象中差距还是很大,需要考虑到各种细节。
今天这个问题有一个比较有意思的应用,就是“约瑟夫环问题”。
具体可以参见百度百科:
http://baike.baidu.com/link?url=poA1Aanlptc6yzP1puYhSw_0RQjRAplhPfHwk6eoiqMNxw6WigCEbexxZ8a9SUbrMGokpPbKNzVYw308xjeEw_
读完问题就可以发现,这个问题用链表就是一个很完美的模拟,双向循环链表就更完美了。(当然也有很多其他的解决方案)
下面是代码:(数据结构部分不需要太多话语解释,更多的是怎么把想象中的数据结构实现成代码)
#include<stdio.h> #include<stdlib.h> typedef struct _node { int num; struct _node *pre,*next; }node; void makenode(node *&N,int i) //创建节点 { node *p; p=(node *)malloc(sizeof(node)); p->num=i; p->pre=N; if (N!=NULL) N->next=p; p->next=NULL; N=p; } void crecylink(node *&L,int n) //创建循环链表 { int i; node *q; makenode(L,1); q=L; for (i=2;i<=n;i++) { makenode(L,i); } L->next=q; q->pre=L; L=q; } void showlink(node *L,int n) //显示链表 { int i; for (i=1;i<=n;i++){ printf("%d ",L->num); L=L->next; } printf("\n"); } void delnode(node *&N) //删除节点 { node *p,*q,*r; q=N; p=N->pre; r=N->next; if (p!=NULL) p->next=r; if (r!=NULL) r->pre=p; free(q); N=r; } void yuesefu(node *&L,int n,int m) //模拟n个人,报数m出局的约瑟夫问题 { crecylink(L,n); int i,j; node *p; p=L; for (i=1;i<=n-1;i++) { for (j=1;j<=m-1;j++) { p=p->next; } delnode(p); showlink(p,n-i); } } int main() { node *p; p=NULL; yuesefu(p,5,2); return 0; }