约瑟夫环

#include<stdio.h>
//#include<math.h>
#include<string.h>
#include<stdlib.h>

typedef struct node{
 int number;
 int psw;
 struct node *next;
}LNode,*LinkList;

int create_circle_linklist(LNode *l)
{
 int num,psw;
 int length = 1;//the node must be behind two because the list will be a circle
 LNode *head;
 head = l;

 printf("please enter the num\n");
 scanf("%d", &num);

 while(num != 0)
 {
  printf("please enter the psw\n");
  scanf("%d", &psw);
  
  l->number = num;
  l->psw = psw;

  if(num != 0)
  {
   //l->next = (LNode *)malloc(sizeof(LNode));
   //l = l->next;
   //length++;

   printf("please enter the num\n");//first we judge the number
   scanf("%d", &num);
   if(num == 0)   //else point the head
   {
    l->next = head;
   }
   else    //if the number aviliable then create the new memery
   {    // so that we can create proper memery space 
    l->next = (LNode *)malloc(sizeof(LNode));
    l = l->next;
    length++;
   }
  }
 }

 return length;
}
/*
  关于动态创建链表时结尾的处理
  create_circle_linklist函数的功能是通过scanf动态为链表赋值,同时计算链表的长度。当输入num值为0时,链表结束,尾指针指向链表头。
 由于传入的是指针,即默认已经创建了链表头,所以我们将length初始化为1,即本身链表头长度为1.
  进入whlie循环,接着为链表头节点赋值。重点就在这里,为链表头中数据赋值,但是对于指针,我们并不知道下一个节点有没有。所以,只有
 先输入数据,判断了是否有下一个节点时,才能决定是继续开空间还是将尾指针指向头部。否则返回的长度值可能出错。
*/

void display_circle_linklist(LNode *l)
{
 LNode *head;
 head = l;

 while(l->next != head)
 {
  printf("%d(%d) -> ", l->number, l->psw);
  l = l->next;
  if(l->next == head)
  {
   printf("%d(%d)\n", l->number, l->psw);
  }
 }
}

int delet_node(LNode *l,int length)
{
 LNode *head,*tmp;
 int num,psw,i;

 head = l;

 printf("please enter the first num\n");
 scanf("%d", &num);
 while(num > length)
 {
  printf("please enter a legal number\n");
  scanf("%d",&num);
 }

 while(length > 1)
 {
  if(num != 1)
  {
   for(i=1; i<num-1 ; i++)
   {
    l = l->next;
   }
  }
  else
  {
   l = tmp->next->next;
  }

  printf("%d ", l->next->number);// print every number which was deleted.
  num = l->next->psw;

  l->next = l->next->next;
  tmp = l;//save the information of node
  l = l->next;
  length--;
 }
 printf("\n");

 printf("the only one is %d\n",l->number);
 return l->number;
}
/*
 while(length > 1)
 {
  if(num != 1)
  {
   for(i=1; i<num-1 ; i++)
   {
    l = l->next;
   }
  }
  else
  {
   l = tmp->next->next;
  }

  printf("%d ", l->next->number);// print every number which was deleted.
  num = l->next->psw;

  l->next = l->next->next;
  tmp = l;//save the information of node
  l = l->next;
  length--;
 }

 num值的不同,程序分情况讨论。由于开始时没有考虑到报数为1的情况,报数为1,即自己报数完毕之后自己退出,我们的环形链表时单向的,
所以如果不做处理,不能找到当前节点的前一个节点。 程序在if(num != 1)中之所以可以找到前节点,是应为我们故意少移动了一位,将当前退出
节点的前一个节点空了出来,但是如果num本身为1,这种方式便行不通了。 所以我们设置了一个LNnode *tmp,用来记录在上一次移动的最后一个节点,
这样,当num为1时,直接拿出这个节点用。

 如何回收内存呢?程序出错了。
*/

void main()
{
 LNode circle;
 int length;

        length  = create_circle_linklist(&circle);
 printf("the number of node is %d\n", length);
 display_circle_linklist(&circle);

 delet_node(&circle,length);
}

你可能感兴趣的:(数据结构,C语言)