算法导论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;
}

 

posted @ 2016-01-13 23:08  lvmememe  阅读(344)  评论(0编辑  收藏  举报