LinkList InitRing(int n, LinkList R) //尾插入法建立单循环链表函数 { ListNode *p, *q; int I; R=q=(LinkNode *)malloc(sizeof(LinkNode)); for(i=1;i<n;i++){ p=(LinkNode *)malloc(sizeof(LinkNode)); q->data=i; q->next=p; q=p; } p->data=n; p->next=R; R=p; return R; } LinkList DeleteDeath(int n, int k, LinkList R) //生者与死者的选择 { int i, j; ListNode *p, *q; p=R; for(i=1; i<n/2; i++){ //删除一半结点 for(j=1; j<k-1; j++) //沿链前进k-1步 p=p->next; q=p->next; p->next=q->next; printf(“%4d”, q->data); free(q); } R=p; return R; } void OutRing(int n, LinkList R){ //输出所有生者 int i; LinkNode *p; p=R; for(i=1;i<=n/2; i++, p=p->next){ printf(“%4d”, p->data) } } 有了上述算法分析和设计之后,实现就比较简单了。首先要定义一个链表结构类型,然后编写一个主函数调用上面已定义好的函数即可。主函数的源程序如下: #include<stdio.h> #include<stdlib.h> typedef struct node{ int data; struct node * next; }ListNode; typedef ListNode * LinkList; void main(){ LinkList R; int n,k; LinkList InitRing(int n, LinkList R); LinkList DeleteDeath(int n, int k, LinkList R); void OutRing(int n, LinkList R); printf(“总人数n. 报数上限k=”); scanf(“%d%d”,&n, &k); R=InitRing(n, R); R=DeleteDeath(n, k, R); OutRing(n, R); } 5 运行结果 编译运行上述程序,提示:总人数n. 报数上限k= 输入30和9后并“回车”可得出如下结果: 9 18 27 6 16 26 7 19 30 12 24 8 22 5 23 21 25 28 29 1 2 3 4 10 11 13 14 15 17 20
时间: 2024-02-15 13:06:10 浏览: 80
这段代码实现了一个约瑟夫环问题的解法,将人们排成一个环,然后按照报数的规则依次淘汰,直到只剩下一半人。其中,InitRing函数用于初始化单向循环链表,DeleteDeath函数用于实现选出要淘汰的节点,OutRing函数用于输出剩下的生者。
具体来说,InitRing函数采用尾插入法,依次将每个人的编号存储在链表节点中,并将链表首尾相连形成一个单向循环链表。
DeleteDeath函数则是按照约定的报数规则,找到要删除的节点,并删除之。该函数在循环中删除一半的节点,直到只剩下一半节点为止。
最后,OutRing函数用于输出剩下的生者的编号,即链表中剩下的节点。
在主函数中,先读入总人数n和报数上限k,然后调用InitRing函数初始化链表,再调用DeleteDeath函数删除一半节点,最后调用OutRing函数输出剩下的生者的编号。
相关问题
LinkList InitRing(int n, LinkList R) //尾插入法建立单循环链表函数 { ListNode *p, *q; int I; R=q=(LinkNode *)malloc(sizeof(LinkNode)); for(i=1;i<n;i++){ p=(LinkNode *)malloc(sizeof(LinkNode)); q->data=i; q->next=p; q=p; } p->data=n; p->next=R; R=p; return R; } LinkList DeleteDeath(int n, int k, LinkList R) //生者与死者的选择 { int i, j; ListNode *p, *q; p=R; for(i=1; i<n/2; i++){ //删除一半结点 for(j=1; j<k-1; j++) //沿链前进k-1步 p=p->next; q=p->next; p->next=q->next; printf(“%4d”, q->data); free(q); } R=p; return R; } void OutRing(int n, LinkList R){ //输出所有生者 int i; LinkNode *p; p=R; for(i=1;i<=n/2; i++, p=p->next){ printf(“%4d”, p->data) } } 有了上述算法分析和设计之后,实现就比较简单了。首先要定义一个链表结构类型,然后编写一个主函数调用上面已定义好的函数即可。主函数的源程序如下: #include<stdio.h> #include<stdlib.h> typedef struct node{ int data; struct node * next; }ListNode; typedef ListNode * LinkList; void main(){ LinkList R; int n,k; LinkList InitRing(int n, LinkList R); LinkList DeleteDeath(int n, int k, LinkList R); void OutRing(int n, LinkList R); printf(“总人数n. 报数上限k=”); scanf(“%d%d”,&n, &k); R=InitRing(n, R); R=DeleteDeath(n, k, R); OutRing(n, R); }
这段代码实现的是约瑟夫问题,即有n个人围成一圈,从第一个人开始报数,报到k的人出圈,直到只剩下一人为止。其中InitRing函数是使用尾插法建立单循环链表,DeleteDeath函数是模拟生者与死者的选择,OutRing函数是输出所有生者。主函数中先获取输入的总人数n和报数上限k,然后调用InitRing函数初始化单循环链表,接着调用DeleteDeath函数进行约瑟夫问题的模拟,最后调用OutRing函数输出所有生者。
请用C语言编写表尾插入法建立带头结点的单链表的算法。 Status CreatLinkL(LinkList &L, int n, ElemType *E){//用表尾插入法建立带头结点的单链表
在C语言中,使用表尾插入法(也称为尾插法)创建带头节点的单链表,我们可以按照以下步骤编写函数`CreatLinkList`:
```c
#include <stdio.h>
#include <stdlib.h>
typedef struct LinkNode {
ElemType data; // 数据域
struct LinkNode* next; // 指针域,指向下一个元素
} LinkNode;
Status CreatLinkList(LinkList* L, int n, ElemType* E) { // 函数声明,传入链表头指针,整数n表示插入的数量,数组E存储数据
if (L == NULL || E == NULL) return ERROR; // 验证输入是否有效
// 初始化链表头节点
L->data = *E;
L->next = NULL;
// 使用循环遍历并插入剩余元素到链表尾部
for (int i = 1; i < n; ++i) {
LinkNode* newNode = (LinkNode*)malloc(sizeof(LinkNode)); // 动态分配内存
if (newNode == NULL) return ERROR; // 检查内存分配是否成功
newNode->data = E[i];
newNode->next = NULL; // 新节点默认不连接其他节点
// 找到当前链表的尾节点并插入新节点
LinkNode* tail = L;
while (tail->next != NULL) {
tail = tail->next;
}
tail->next = newNode; // 将新节点链接到尾节点之后
}
return OK; // 插入成功
}
阅读全文