循环单向链表(约瑟夫环)

#include <stdio.h>  
#include <stdlib.h> 

typedef struct List
{
    int data;
    struct List *next;
}List;

//创建循环单向链表n为长度
List *list_create(int n)
{
    List *head, *p;
    int i;

    head = (List *)malloc(sizeof(List));
    p = head;
    p->data = 1;             //创建第一个结点

    for (i = 2; i <= n; i++)//创建剩余结点
    {
        p->next = (List *)malloc(sizeof(List));
        p = p->next;
        p->data = i;
    }
    p->next = head;
    return head;
}
//打印循环链表
void list_print(List *head)
{
    List *index;
    printf("%d\t",head->data);//输出第一个节点
    index = head->next;
    while (index != head)    //判断是否是最后一个结点
    {
        printf("%d\t",index->data);
        index = index->next;
    }
}
//统计循环链表长度
int list_len(List *head)
{
    List *index;
    int count = 0;
    index = head->next;
    count = 1;
    while (index != head);
    {
        count++;
        index = index->next;
    }
    printf("\n%d\n",count);
    return count;
}
//插入数据index插入位置,data插入数据
List *list_addnote(List *head, int index, int date)
{
    List *p,*pNew,*q;
    int i = 0;
    p = head;
    while (i < index - 1)  //查找结点
    {
        p = p->next;
        i++;
    }

    pNew = (List *)malloc(sizeof(List));//为新结点申请空间
    pNew->data = date;
    q = p->next;                        //保存插入后结点
    p->next = pNew;
    pNew->next = q;
    return head;
}
//删除值为date的结点
List *list_delnote(List *head,int date)
{
    List *p,*per;
    per = head;
    p = head->next;
    while (p->data != date) //查找结点
    {
        per = p;            //前驱结点
        p = p->next;
    }
    per->next = p->next;
    if (p == head)       //如果删除的是头结点,则头结点应指向下一个
        head = head->next;
    free(p); 
    return head;
}
// 约瑟夫环已知n个人(以编号1,2,3...n分别表示)围坐在一张圆桌周围。
//从编号为k的人开始报数,数到m的那个人出列;他的下一个人又从1开始报数,
//数到m的那个人又出列;依此规律重复下去,直到圆桌周围的人全部出列
void list_process(List *head, int k, int m)
{
    List *p, *q;
    int i = 1;
    p = head;
    while (i < k)       //查找编号k的位置
    {
        p = p->next;
        i++;
    }
    while (p->next != p)//判断是否只剩最后一个结点
    {
        for (i = 1; i < m - 1; i++)//开始报数
        {
            p = p->next;
        }
        q = p->next;             //需要删除的数据
        p->next = p->next->next; //将删除的空间指向转变
        p = p->next;
        printf("%d\t",q->data);
        free(q);
    }
    printf("%d\t", p->data); //最后一个
    free(p);
}
int main(void)
{
    List *head;
    head = list_create(10);
    head = list_addnote(head,5,18);
    head = list_delnote(head,1);
    list_print(head);
    printf("\n\n");
    list_process(head, 2, 3);
    system("pause");
    return 0;
}
posted @ 2015-11-03 22:00  黑暗里的影子  阅读(343)  评论(0编辑  收藏  举报