首页 新闻 会员 周边 捐助

单链表实现约瑟夫循环,编译未出错,结果没有显示

0
悬赏园豆:5 [待解决问题] 浏览: 33次

希望大家可以帮我看看

include <stdio.h>

include <stdlib.h>

include"file.h"

typedef int ElemType;
typedef int Status;

typedef struct QNode {
int id;
struct QNode* next;
} QNode,*QueuePtr;
typedef struct {
QueuePtr front;
QueuePtr rear;
}LinkQueue;

Status InitQueue(LinkQueue& Q);
Status DestroyQueue(LinkQueue& Q);
Status ClearQueue(LinkQueue& Q);
Status QueueEmpty(LinkQueue& Q);
int QueueLength(LinkQueue& Q);
QueuePtr GetHead(LinkQueue& Q,ElemType &e);
Status EnQueue(LinkQueue& Q,ElemType e);
Status DeQueue(LinkQueue& Q,ElemType &e);
void visit(LinkQueue Q);
Status QueueTraverse(LinkQueue Q,void visit(LinkQueue Q));
void Josephus(LinkQueue& Q, int k, int m);

Status InitQueue(LinkQueue& Q){
Q.front=(QueuePtr)malloc(sizeof(QNode));
if(!Q.front) {
printf("初始化失败\n");
exit(OVERFLOW);
}
Q.front->next=NULL;
return OK;
}
Status DestroyQueue(LinkQueue& Q){
while(Q.front){
Q.rear=Q.front->next;
free(Q.front) ;
Q.front=Q.rear;
}
return OK;
}
Status ClearQueue(LinkQueue& Q){
QueuePtr p = Q.front;
while (p) {
QueuePtr temp = p->next;
free(p);
p = temp;
}
if (Q.front== Q.rear) return ERROR;
return OK;
}
Status QueueEmpty(LinkQueue& Q){
return Q.front == Q.rear;
}
int QueueLength(LinkQueue& Q) {
int count = 0;
QueuePtr p = Q.front->next;
while (p) {
count++;
p = p->next;
}
return count;
}
QueuePtr GetHead(LinkQueue& Q, ElemType &e) {
if (Q.front == Q.rear) return NULL;
e = Q.front->next->id;
return Q.front->next;
}
Status EnQueue(LinkQueue& Q,ElemType e){
QueuePtr p ;
p=(QueuePtr)malloc(sizeof(QNode));
if(!p) exit(OVERFLOW);
p->id=e; p->next=NULL;
Q.rear->next=p;
Q.rear=p;
return OK;
}
Status DeQueue(LinkQueue& Q,ElemType &e){
if (Q.front== Q.rear) return ERROR;
QueuePtr p ;
p=Q.front->next;
e=p->id;
Q.front->next=p->next;
if (p== Q.rear) Q.rear==Q.front ;
free(p);
return OK;
}
void visit(QueuePtr p) {
printf("%d ", p->id);
}
Status QueueTraverse(LinkQueue Q, void (*visit)(QueuePtr)) {
QueuePtr p = Q.front->next;
while (p) {
visit(p);
p = p->next;
}
printf("\n");
return OK;
}
void Josephus(LinkQueue& Q, int k, int m) {
QueuePtr p = Q.front;
// 移动到开始报数的位置
for (int i = 0; i < k - 1; i++) {
p = p->next;
}
// 开始报数
while (QueueLength(Q) > 0) {
for (int i = 1; i < m; i++) {
p = p->next;
if (p == Q.front) p = p->next; // 跳过头节点
}
// p指向的节点出列
QueuePtr temp = p->next;
printf("出列的人是:%d\n", temp->id);
p->next = temp->next;
if (temp == Q.rear) Q.rear = p; // 如果出列的是尾节点,则更新尾节点
free(temp);
if (p->next == Q.front) p = p->next; // 如果下一个节点是头节点,则跳过头节点
}
}

int main() {
LinkQueue Q;
int n, k, m;
printf("请输入人数n、开始报数的位置k和数到m的人出列:");
scanf("%d %d %d", &n, &k, &m);

InitQueue(Q);
for (int i = 1; i <= n; i++) {
    EnQueue(Q, i);
}
Josephus(Q, k, m);
DestroyQueue(Q);
return 0;

}
//file.h

include<stdio.h>

define TRUE 1

define FALSE 0

define OK 1

define ERROR 0

define INFEASIBLE -1

define OVERFLOW -2

define Stack_INT_SIZE 100

define StackIncrement 10

define OPSETSIZE 7

布海的主页 布海 | 初学一级 | 园豆:197
提问于:2024-11-03 11:28
< > 人人可用的开源BI工具
分享
所有回答(1)
0

根据你提供的代码实现和描述,程序的目标是实现约瑟夫环的逻辑,但你提到编译无错误但结果没有显示。下面是对你的代码可能存在问题的分析及一些修改建议,确保程序能够正常工作并输出正确的结果。

代码中的问题

  1. 头文件包含语法错误:

    • include <stdio.h> 行应改为 #include <stdio.h>,同样,#include "file.h" 也应加上 #
  2. 结构体指针的使用:

    • Josephus 函数和 visit 函数中的参数类型定义不一致,函数 void visit(QueuePtr p)QueueTraverse 的原型不匹配。
    • Josephus 函数的 QueueLength(Q) 计算逻辑可以直接用 p 来做,而不是使用 QueueLength(Q),因为每次循环都会造成不必要的遍历。
  3. 对尾指针的管理:

    • DeQueue 函数中的 if (p== Q.rear) Q.rear==Q.front ; 这个赋值是错误的,应使用 = 而不是 ==,且对 rear 节点的更新可能需要更多的检查。
  4. 内存管理:

    • 尾指针可能需要更多的条件检查,以确保没有意外挂掉。
  5. 主函数前的初始化:

    • InitQueue 函数并未将 Q.rear 指向 Q.front,应该在初始化中将 rear 指向 front

修改后的代码

以下是修改后的实现,确保这些问题得到纠正。请注意这些变更:

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

typedef int ElemType;
typedef int Status;

typedef struct QNode {
    int id;
    struct QNode* next;
} QNode, *QueuePtr;

typedef struct {
    QueuePtr front;
    QueuePtr rear;
} LinkQueue;

Status InitQueue(LinkQueue& Q);
Status DestroyQueue(LinkQueue& Q);
Status ClearQueue(LinkQueue& Q);
Status QueueEmpty(LinkQueue& Q);
int QueueLength(LinkQueue& Q);
QueuePtr GetHead(LinkQueue& Q, ElemType &e);
Status EnQueue(LinkQueue& Q, ElemType e);
Status DeQueue(LinkQueue& Q, ElemType &e);
void visit(QueuePtr p);
Status QueueTraverse(LinkQueue Q, void (*visit)(QueuePtr));
void Josephus(LinkQueue& Q, int k, int m);

Status InitQueue(LinkQueue& Q) {
    Q.front = (QueuePtr)malloc(sizeof(QNode));
    if (!Q.front) {
        printf("初始化失败\n");
        exit(OVERFLOW);
    }
    Q.rear = Q.front; // 将 rear 指向 front
    Q.front->next = NULL;
    return OK;
}

Status DestroyQueue(LinkQueue& Q) {
    while (Q.front) {
        Q.rear = Q.front->next;
        free(Q.front);
        Q.front = Q.rear;
    }
    return OK;
}

Status ClearQueue(LinkQueue& Q) {
    QueuePtr p = Q.front;
    while (p) {
        QueuePtr temp = p->next;
        free(p);
        p = temp;
    }
    if (Q.front == Q.rear) return ERROR;
    return OK;
}

Status QueueEmpty(LinkQueue& Q) {
    return Q.front == Q.rear;
}

int QueueLength(LinkQueue& Q) {
    int count = 0;
    QueuePtr p = Q.front->next;
    while (p) {
        count++;
        p = p->next;
    }
    return count;
}

QueuePtr GetHead(LinkQueue& Q, ElemType &e) {
    if (Q.front == Q.rear) return NULL;
    e = Q.front->next->id;
    return Q.front->next;
}

Status EnQueue(LinkQueue& Q, ElemType e) {
    QueuePtr p;
    p = (QueuePtr)malloc(sizeof(QNode));
    if (!p) exit(OVERFLOW);
    p->id = e; 
    p->next = NULL;
    Q.rear->next = p;
    Q.rear = p; // 将 rear 更新
    return OK;
}

Status DeQueue(LinkQueue& Q, ElemType &e) {
    if (Q.front == Q.rear) return ERROR;
    QueuePtr p;
    p = Q.front->next;
    e = p->id;
    Q.front->next = p->next;
    if (p == Q.rear) Q.rear = Q.front; // 更新 rear 在队空时指向 front
    free(p);
    return OK;
}

void visit(QueuePtr p) {
    printf("%d ", p->id);
}

Status QueueTraverse(LinkQueue Q, void (*visit)(QueuePtr)) {
    QueuePtr p = Q.front->next;
    while (p) {
        visit(p);
        p = p->next;
    }
    printf("\n");
    return OK;
}

void Josephus(LinkQueue& Q, int k, int m) {
    QueuePtr p = Q.front;
    
    // 移动到开始报数的位置
    for (int i = 0; i < k - 1; i++) {
        p = p->next; // 指向第 k 个元素
    }
    
    // 开始报数
    while (QueueLength(Q) > 0) {
        for (int i = 1; i < m; i++) {
            p = p->next;
            if (p == Q.front) p = p->next; // 跳过头节点
        }
        // p指向的节点出列
        QueuePtr temp = p->next;
        printf("出列的人是:%d\n", temp->id);
        p->next = temp->next;
        if (temp == Q.rear) Q.rear = p; // 如果出列的是尾节点,则更新尾节点
        free(temp);
        if (p->next == Q.front) p = p->next; // 如果下一个节点是头节点,则跳过头节点
    }
}

int main() {
    LinkQueue Q;
    int n, k, m;
    printf("请输入人数n、开始报数的位置k和数到m的人出列:");
    scanf("%d %d %d", &n, &k, &m);
    
    InitQueue(Q);
    for (int i = 1; i <= n; i++) {
        EnQueue(Q, i);
    }
    
    Josephus(Q, k, m);
    
    DestroyQueue(Q);
    return 0;
}

代码变更要点

  • 改正了包含文件的语法错误。
  • InitQueue 函数中将 rear 指向 front 完成初始化。
  • 确保在 DeQueue 中对 rear 的更新使用 = 号而不是 ==
  • 修复了 visit 和其他函数中的指针类型不匹配的问题。

希望看到的结果

运行该程序后,输入正确的参数后,你应该能看到出列的人,直到最后所有人都被处理。

如果还有问题或者其他任何具体问题,欢迎随时问我!

Technologyforgood | 园豆:7872 (大侠五级) | 2024-12-02 08:48
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册
Top