c语言_数据结构_单向循环链表

  单向循环链表是单链表的一种改进,是将单链表的首尾结点相连的一种结构。其结构图如下:

c语言_数据结构_单向循环链表

 c语言_数据结构_单向循环链表_第1张图片

单向循环链表的创建:

 

#include  
#include  
#include  
#include 
 
typedef int datatype;
 
typedef struct node
{
   datatype data;
   struct node *next;
}listnode, *linklist;
 

//可以包含头结点,也可以不创建头结点,仅存在头指针入口
linklist init_list(void)
{
   return NULL;//此处不创建头结点
}

//插入。对于循环列表,若仅存在一个结点,则其next指针指向本身;对于表中存在多个结点的,其末结点的nxet指针域指向头结点。遍历到末结点后,断开与头结点相连,将新结点插入变成新的末结点。如图:
c语言_数据结构_单向循环链表_第2张图片

linklist insert(linklist head, datatype i)
{
   linklist newnode = (linklist)malloc(sizeof(listnode));
   newnode->data = i;
 
   if(head == NULL)   //第一个结点next指向自己
   {   
      newnode->next = newnode;
       return newnode;
   }
 
   linklist p = head;
   while(p->next != head)//遍历各结点,当结点的next指向头结点时,该结点为末结点。
   p = p->next;
 
   newnode->next = p->next;
   p->next = newnode;
 
   return head;//无论插入多少个,返回的都是第一个结点(非头结点)的地址。
}

 
//Josephy游戏:建立包含若干整数的单向循环链表,从第一个节点开始数,把数到3的结点删除,接着下一结点开始数,数到3继续删除。以此类推打印最后剩余的结点。
 
linklist Josephu(linklist head)
{
   if(head == NULL)
   return NULL;
 
   linklist p=head->next, s=head->next->next;
 
   while(s != s->next)
   {
      p->next = s->next;
      free(s);
 
      p = p->next->next;
      s = p->next;
   }
 
   return s;
}

 
void show(linklist head)
{
   if(head == NULL)
   return;
 
   linklist p = head;
   while(p->next != head)
   {
      printf("%d\t", p->data);
      p = p->next;
   }
   printf("%d\n", p->data);
   return;
}

 
int main(void)
{
   linklist head;
   head = init_list();
 
   int n;
   scanf("%d", &n);
 
   int i;
   for(i=1; i<=n; i++)
   {
      head = insert(head, i);
   }
 
   show(head);
   linklist ans = Josephu(head);
   printf("%d\n", ans->data);
 
   return 0;
}
 


你可能感兴趣的:(C)