数据结构与算法作业3——约瑟夫环问题(循环链表)

 第二次作业:

习题2 载具杀手与时停高手(约瑟夫环问题)

著名绅士简尚夫有一项特殊的天赋,他可以摧毁任意一辆载具(载具杀手)。他的朋友狄傲可以将时间暂停(时停高手)。他俩玩一个游戏。

有N辆车,编号1~N。其中编号A的是狄傲心爱的压路机。指定编号B的车作为起点,简尚夫首先摧毁这辆车;然后往后数K辆车,摧毁第K辆;然往后数K辆车,摧毁第K辆。数到最后一辆车,则回到剩余的第一辆车接着数。直到把所有车全部摧毁。当简尚夫将要摧毁狄傲的压路机时,狄傲会发动时停技能阻止他。

请你构建循环链表,模拟这个过程(模拟到发动时停技能时为止)
最后按顺序打印时停技能发动时,剩下的车的编号
 

输入:四个整数,空格隔开。
N : 车的数目。
A : 压路机的编号。
B : 作为起点的车的编号。
K : 每次跳过的车的数目。

输出:若干整数,空格隔开。
剩下的车的编号。

示例:
(输入)5 2 3 2
(输出)1 2 4
(说明)
初始:1->2->3->4->5->
摧毁第一辆车后:1->2->4->5->
摧毁第二辆车后:1->2->4->
下一辆要摧毁的车狄傲的压路机,于是他发动了时停,游戏结束。输出:1 2 4

循环链表节点类型定义(供参考):
struct ListNode {
int val;
ListNode *next;
};

刚开始总体骨架的构造出现问题,经过研究与提问,得到了最终的答案:
csdn版(有代码):

C循环链表程序出现Process returned -1073741819 (0xC0000005)的问题-编程语言-CSDN问答https://ask.csdn.net/questions/7521382?spm=1005.2025.3001.5141&weChatOA=StackOverflow版(原汁原味):

c - CodeBlocks gives "Process returned -1073741819 (0xC0000005)", with 0 error nd 0 warning when I create a linked list cycle - Stack Overflowhttps://stackoverflow.com/questions/69380138/codeblocks-gives-process-returned-1073741819-0xc0000005-with-0-error-nd-0/69380437#69380437

可是随后,我发现貌似使用结构体数组并没有什么意义,本来是为了好找每个结点,但是要是按照我在函数内部定义数组,那么由于 a[] 是一个自动变量(局部变量),我在外面仍然调用不了里面的 a[i] 的结点,因此我选择普通的结点,

但是要使用 *head 以及 *tail 来表示循环链表的头尾位置,这样,

(1)我们使用 *head 便于从头部向尾部进行遍历每个结点

(2)我们使用 *tail 便于进行尾插法的操作 *****

注:普通链表的头插法需要头指针,尾插法需要尾指针。


接下来:

在编程的过程中,出现了最大的问题就是:

在if判断条件的书写时,把比较是否相等的 == 当作了

于是,调了好长时间,终于在人眼 debug 的时候发现了

另外,告诉我一个道理,充分的运动有利于 bug 的寻找。

以下是目前的代码,
实现了基本的功能,但是在车车的总数为1的时候,程序会报错(如输入"1 1 1 1")。

#include <stdio.h>
#include <stdlib.h>
typedef struct ListNode
{
    int val;
    struct ListNode* next;
} ListNode;

///*
//makenode:
//input: *p(last node), val
//*/
//ListNode* makenode(ListNode* p, int value)
//{
//	ListNode* new_node = (ListNode*)malloc(sizeof(ListNode));
//	p->next = new_node;
//	new_node->val = value;
//	new_node->next = NULL;
//	return new_node;
//}

/*
makecycle:
input: **head, **tail, N, A
*/
void makecycle(ListNode** head_ref, ListNode** tail_ref, int N, int A)
{
    int i;
    ListNode* new_node = NULL;
    (*head_ref)->val = 1;
    (*head_ref)->next = NULL;
    (*tail_ref) = (*head_ref);
    for(i = 1; i < N; i++)
    {
        new_node = (ListNode*)malloc(sizeof(ListNode));
        (*tail_ref)->next = new_node;
        (*tail_ref)->val = i;
        printf("%d->", (*tail_ref)->val);//test
        (*tail_ref) = new_node;
        new_node->next = NULL;
        new_node->val = i+1;
    }
    printf("%d", (*tail_ref)->val);//test
    new_node->next = (*head_ref);
    printf("\n------------------------------\n");
}

/*
denode:
input: **head, **tail, N, A, B, K
*/
int denode(ListNode** head_ref, ListNode** tail_ref, int N, int A, int B, int K)
{
    ListNode* p = (*head_ref);
    ListNode* q = (*head_ref);
    //ListNode* r = NULL;
    int i, j;
    //
    if(B != 1)
    {
        for(i = 1; i < B-1; i++)
        {
            if(p != NULL) p = p->next;
        }
    }
    else
    {
        p->next = (*head_ref);
    }
    //
    for(i = 1; i < A; i++)
    {
        if(q != NULL) q = q->next;
    }
    //
    for(;;)
    {
        //
        if((p->next != NULL)&&(p->next != q)&&(p->next != (*head_ref)))
        {
            printf("the deleted node: %d\n", p->next->val);
            p->next = p->next->next;
        }
        //
        if(p->next == q)
        {
            return 0;
        }
        //
        if(p->next == (*head_ref))
        {
            (*head_ref) = (*head_ref)->next;
            printf("the deleted node: %d\n", p->next->val);
            p->next = p->next->next;
        }
        //
        for(j = 1; j < K; j++)
        {
            p = p->next;
        }

    }



}

int main()
{
    int N, A, B, K;
    printf("N : 车的数目。\nA : 压路机的编号。\nB : 作为起点的车的编号。\nK : 每次跳过的车的数目。\n");
    ListNode* p = NULL;
    //input
    scanf_s("%d %d %d %d", &N, &A, &B, &K);

    //head node, tail node
    ListNode* head = (ListNode*)malloc(sizeof(ListNode));
    ListNode* tail = (ListNode*)malloc(sizeof(ListNode));
    //makecylce
    makecycle(&head, &tail, N, A);
    //denode
    denode(&head, &tail, N, A, B, K);
    //output
    p = head;
    do
    {
        printf("%d ", p->val);
        p = p->next;
    }
    while(p != head);
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值