希望大家可以帮我看看
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>
行应改为 #include <stdio.h>
,同样,#include "file.h"
也应加上 #
。结构体指针的使用:
Josephus
函数和 visit
函数中的参数类型定义不一致,函数 void visit(QueuePtr p)
和 QueueTraverse
的原型不匹配。Josephus
函数的 QueueLength(Q)
计算逻辑可以直接用 p
来做,而不是使用 QueueLength(Q)
,因为每次循环都会造成不必要的遍历。对尾指针的管理:
DeQueue
函数中的 if (p== Q.rear) Q.rear==Q.front ;
这个赋值是错误的,应使用 =
而不是 ==
,且对 rear
节点的更新可能需要更多的检查。内存管理:
主函数前的初始化:
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
和其他函数中的指针类型不匹配的问题。运行该程序后,输入正确的参数后,你应该能看到出列的人,直到最后所有人都被处理。
如果还有问题或者其他任何具体问题,欢迎随时问我!