c语言用无头结点的循环链表解决约瑟夫环问题 出现段错误

img

#include<stdio.h>
#include<stdlib.h>
typedef struct node
{
struct node *next;
int date;
} Lnode, *linklist;
void createlist(linklist L,int n)//建立一个无头结点的循环链表
{
int i;
L = (linklist)malloc(sizeof(Lnode));
L->date = 1;
linklist h = L;
for (i = 2; i <= n; i++)
{
linklist t;
t = (linklist)malloc(sizeof(Lnode));
t->date = i;
h->next = t;
h = h->next;
}
h->next = L;
}
int deletenode(linklist q,int key)//删除并返回指定结点
{
int i,e;
for (i = 0; i < key - 2;i++)
{
q = q->next;
}
linklist pp;
pp = q->next;
e = pp->date;
q->next = pp->next;
free(pp);
return e;
}
int main()
{
int n, p;
scanf("%d %d", &n, &p);
linklist L;
createlist(L,n);
linklist q=L;//辅助指针
int i,a[n];
if(p==1)//p为1的特例
{
for (i = 1; i <= n;i++)
a[i] = i;
}
else
{
for (i = 0; i < n; i++)
{
a[i] = deletenode(q, p);//把依次从链表里删除的数存储到数组里
}
}
for (i = 1; i <= n;i++)//输出
{
printf("%d ", a[i]);
}
return 0;
}

  1. createlist 里创建一个新的node是其next应该初始化为空
  2. 当链表中元素少于p (key)的时候,deletenode中的
    for (i = 0; i < key - 2;i++)
    {
    q = q->next;
    }
    
    q会在循环结束前就已经为NULL(但你malloc的时候没有初始化为NULL, 会出现无法意料的情况),当判断q为NULL,但循环还未结束时是不是应该从头再数?

下面时我的一个循环链表实现

#include <stdio.h>
#include <stdlib.h>

typedef struct node Node;
struct node {
    int key;
    Node *next;
};


Node *create_j_ring(int ring_sz)
{
    Node *j_head = NULL;
    Node *p;
    Node *p_prev;
    int i = 0;

    while (i++ < ring_sz) {
        p = (Node *)malloc(sizeof(struct node));
        p->key = i;
        p->next = NULL;
        if (!j_head) {
            j_head = p;
        }
        else {
            p_prev->next = p;
        }
        p_prev = p;
    }
    p->next = j_head;
    
    return j_head;
}

void exit_j_ring(Node *j_ring, int num)
{
    Node *p, *prev;
    Node *piter;
    int count = 1;

    p = j_ring;
    while(p->next != j_ring) {
        p = p->next;
    }
    prev = p;

    piter = j_ring;
    while (piter) {
        if (count == num) {
            prev->next = piter->next;
            printf(" %d", piter->key);
            free(piter);

            // last node has exited?
            if (piter != prev)
                piter = prev->next;
            else
                piter = NULL;
            count = 1;
        }
        else {
            prev = piter;
            piter = piter->next;
            count++;
        }
    }
}

void dump_j_ring(Node *j_ring, int size)
{
    for (int i = 0; i < size; i++) {
        printf(" %d", j_ring->key);
        j_ring = j_ring->next;
    }
    printf("\n");
}
        
int main(void)
{
    int ring_sz;
    int num;
    Node *j_ring = NULL;

    printf("Please input Josephus ring size:");
    scanf("%d", &ring_sz);
    printf("\n");
    printf("Please input number to exit:");    
    scanf("%d", &num);

    if (ring_sz <= 0 || num <= 0) {
        printf("invalid input\n");
        return -1;
    }

    j_ring = create_j_ring(ring_sz);

    dump_j_ring(j_ring, ring_sz);

    exit_j_ring(j_ring, num);
}