循环链表
单链表的局限性:如果不从头结点出发,就无法访问的全部节点。
循环链表定义:将单链表终端结点的指针由空指针改为指向头结点;使单链表形成一个环,称单循环链表,简称循环链表

注:循环链表不一定有头结点。
约瑟夫环问题
问题描述:N个人围成一圈,从第一个人开始报数,报到m的人出圈,剩下的人继续从1开始报数,报到m的人出圈;如此往复,直到所有人出圈。(模拟此过程,输出出圈的人的序号)
1 #include <stdio.h> 2 #include <malloc.h> 3 4 typedef struct Node{ 5 int data;//数据 6 struct Node *next;//游标(cursor) 7 }node; 8 9 node * create(int,node **); 10 void fun(node **,node **,int); 11 12 void fun(node **head,node **rear,int m){ 13 node *p=*head; 14 node *q; 15 int n=m; 16 if(*head == *rear){ 17 printf("最后一个出圈人的序号是%d;\n",(*rear)->data); 18 free(*rear); 19 }else{ 20 while(n>2){ 21 p=p->next; 22 n--; 23 } 24 q=p->next; 25 printf("%d => ",q->data); 26 *head=q->next; 27 *rear=p; 28 p->next=p->next->next; 29 free(q); 30 fun(head,rear,m); 31 } 32 } 33 34 node *create(int n,node **rear){ 35 node *p,*head,*a; 36 int i=1; 37 head=(node *)malloc(sizeof(node)); 38 p=head; 39 if(i != n){ 40 while(i<=n){ 41 a=(node *)malloc(sizeof(node)); 42 a->data=i++; 43 p->next=a; 44 p=a; 45 } 46 p->next=head->next; 47 *rear=p; 48 } 49 free(head); 50 return p->next; 51 } 52 53 void main(){ 54 int n,m; 55 node *head,*rear; 56 printf("请输入约瑟夫人数:"); 57 scanf("%d",&n); 58 head=create(n,&rear); 59 printf("请输入m:"); 60 scanf("%d",&m); 61 fun(&head,&rear,m); 62 }
发牌问题
问题描述:将13张牌按一定顺序排放;从1开始数,依次数到1-13;每次数的时候;若不是结束位置,就将该牌放置末尾;若是结束为止,将结束位置翻出并取出,为本次数到的数。
方法:将头指针指向的结点元素设置为1,并将结点指向的结点赋值给指针
将头指针指向向后移动 i 次,每次都判断结点的值是否为0,若不为0.则i自减1;
1 #include <stdio.h> 2 #include <malloc.h> 3 #define NUM 13 4 5 typedef struct node{ 6 int data;//数据 7 struct node *next;//指针域 8 }Node,* PNode; 9 10 PNode creat(); 11 void printList(PNode); 12 void fun(PNode *,int); 13 14 void fun(PNode *head,int k){ 15 int i=1; 16 PNode p=*head; 17 while(i<k){ 18 p=p->next; 19 if(p->data!=0) 20 i--; 21 i++; 22 } 23 p->data=k; 24 *head=p->next; 25 if(k!=NUM){ 26 fun(head,k+1); 27 } 28 } 29 30 void printList(PNode head){ 31 PNode p=head->next; 32 printf("%d ",head->data); 33 while(p!=head){ 34 printf("%d ",p->data); 35 p=p->next; 36 } 37 printf("\n"); 38 } 39 40 PNode creat(){ 41 PNode head,p,q; 42 int i=0; 43 head=(PNode)malloc(sizeof(Node)); 44 p=head; 45 while(i<NUM){ 46 q=(PNode)malloc(sizeof(Node)); 47 q->data=0; 48 p->next=q; 49 p=q; 50 i++; 51 } 52 q->next=head->next; 53 p=head->next; 54 free(head); 55 return p; 56 } 57 58 void main(){ 59 PNode head,p; 60 int i=1; 61 head=creat(); 62 p=head; 63 fun(&p,i); 64 printList(head); 65 }
1 //发牌问题用迭代实现 2 void fun(int a[],int n){ 3 int i,j=0,k=0,p; 4 for(i=0;i<n;i++){ 5 j=0; 6 while(j<i){ 7 if(a[k]!=0) 8 j--; 9 j=(j+1)%n; 10 k=(k+1)%n; 11 } 12 p=k; 13 while(a[k]!=0){ 14 k=(k+1)%n; 15 if(k==p) 16 break; 17 } 18 a[k]=i+1; 19 } 20 }
双向链表
- 双向链表的指针域有两个指针,分别指向他的前驱和后继;
- 双向链表最后一个结点的后继指向头结点;头结点的前驱指向最后一个结点;

1 #include <stdio.h> 2 typedef int ElemType; 3 4 typedef struct DualNode{ 5 ElemType data;//数据 6 struct DualNode *prior;//前驱结点 7 struct DualNode *next;//后继结点 8 }DualNode,* DuLinkList;
浙公网安备 33010602011771号