C语言的代码,球解释

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define M 4 //标签个数
#define N 3 //标签位数

//定义单链队列结构体
typedef struct QNode{
char *qelem;
struct QNode *next;
}QNode,*QueuePtr;//定义了一个结点数据类型QNode和一个指针数据类型QueuePtr(指向QNode)

typedef struct
QueuePtr front;//头指针,指向头结点
QueuePtr rear;//尾指针,指向尾结点
}LinkQueue;//定义了一个链队列数据类型LinkQueue

//初始化队列
void InitQueue(LinkQueue *Q){
(*Q).front=(*Q).rear=(QueuePtr)malloc(sizeof(QNode)+N+1);
(*Q).front->next=NULL;
}
//入队
void EnQueue(LinkQueue *Q,char *elem){
QueuePtr p=(QueuePtr)malloc(sizeof(QNode)+N+1);
p->qelem=(char *)p+sizeof(QNode);
strcpy(p->qelem,elem);
p->next=NULL;
(*Q).rear->next=p;
(*Q).rear=p;
}

//出队
QNode* DeQueue(LinkQueue *Q){
QueuePtr p;
p=(*Q).front->next;
(*Q).front->next=p->next;
p->next=NULL;
return(p);
}

//判断队列是否为空
int IsEmpty(LinkQueue Q){
if(Q.front->next==NULL) return(1);//队列为空,返回1
else return(0);
}

//前缀检索函数
int Prefix(char *q1,char *q2){
int flag=0;
for(;*q1!='\0';){
if(*q1==*q2) {q1++;q2++;}
else {flag=1;break;}
}
if(flag==0) return(1);//q1是q2的前缀
else return(0);
}

//打印队列的当前值
void PrintQueue(LinkQueue *Q){
QueuePtr p=(QueuePtr)malloc(sizeof(QNode)+N+1);
p=(*Q).front->next;
printf("Q=< ");
for(;p!=NULL;p=p->next){
printf("%s ",p->qelem);
}
printf(">\n");
}

void main(){
LinkQueue Q;
InitQueue(&Q);
char *a="0";
char *b="1";
EnQueue(&Q,a);
EnQueue(&Q,b);
while(!IsEmpty(Q)){
PrintQueue(&Q);
//pointer指向标签ID组成的字符串:
//这里的标签ID个数、位数要分别与宏定义中的M、N保持一致。
char *pointer="000,001,101,110";
int count=0;
int i=0;
printf("发送请求%s\n",Q.front->next->qelem);
for(;i<M;i++,pointer+=(N+1)*sizeof(char)){
if(Prefix(Q. front->next->qelem,pointer)) count++;
}
QNode *pp=DeQueue(&Q);
printf("Update Q:");
PrintQueue(&Q);
char s[N+1];
strcpy(s,pp->qelem);
printf("响应的标签数count=%d\n",count);
if(count==0) {printf("没有标签响应\n");printf("\n");}
else if(count>=2){
EnQueue(&Q,strcat(pp->qelem,"0"));
EnQueue(&Q,strcat(s,"1"));
printf("冲突,重置Q:");
PrintQueue(&Q);
printf("\n");
}
else {printf("读标签\n");printf("\n");}
}
}

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define M 4 //标签个数
#define N 3 //标签位数

//定义单链队列结构体
typedef struct QNode{
char *qelem;
struct QNode *next;
}QNode,*QueuePtr;//定义了一个结点数据类型QNode和一个指针数据类型QueuePtr(指向QNode)

typedef struct
QueuePtr front;//头指针,指向队列头结点
QueuePtr rear;//尾指针,指向队列尾结点
}LinkQueue;//定义了一个链队列数据类型LinkQueue

//初始化队列
void InitQueue(LinkQueue *Q){
(*Q).front=(*Q).rear=(QueuePtr)malloc(sizeof(QNode)+N+1); //队列的头尾指针指向同一个一个新分配的结点,这个结点的大小是在QNode(32位系统上8个字节)
//的基础上再分配N+1个字节,可以将这个队列理解成贪吃蛇,这个结点是蛇头
//和蛇尾最初指向的位置
(*Q).front->next=NULL; //头指针指向的结点的next指针置为NULL
}
//入队
void EnQueue(LinkQueue *Q,char *elem){
QueuePtr p=(QueuePtr)malloc(sizeof(QNode)+N+1); //新分配一个结点
p->qelem=(char *)p+sizeof(QNode); //qelem指向的位置是QNode后面
strcpy(p->qelem,elem); //将传入的字符串elem拷贝到指针p->qulem指向的位置,即P结点中QNode后面的N+1个字节内
p->next=NULL; //新结点的next指针置为NULL
(*Q).rear->next=p; //将p结点放到队列的尾指针rear指向的结点之后
(*Q).rear=p; //移动尾结点指针指向新插入队列的结点

/*
入队列就是蛇吃了一块之后在蛇尾长出来,蛇尾指针指向这个新长出来的位置
example:
插入前
------------------------
|A|B |C |N |.....|N |  
-|----------------|-----
|________________|__________________________Q->front指向的位置即蛇头
|__________________________Q->rear指向的位置即蛇尾

插入后
------------------------
|A|B |C |N |.....|N | P 
-|--------------------|--
|____________________|_______________________Q->front指向的位置即蛇头
|________________________Q->rear指向的位置即新的蛇尾

*/
}

//出队
QNode* DeQueue(LinkQueue *Q){
QueuePtr p;
p=(*Q).front->next; //取出Q->front指向的下一个结点,即蛇头之后的第一个吃进去的结点P
(*Q).front->next=p->next; //将第一个结点指向的下一个结点赋给蛇头结点Q->front来指向,即蛇头此时指向之前的那个第二结点
p->next=NULL; //出队列的结点单独一个,不再指向之前的第二结点了,所以置为NULL
return(p); //将出列的结点返回

/*
出队列就是蛇吐出蛇头之下的第一个结点也就是第一个吃进去的结点
example:
插入前
------------------------
|A|B |C |N |.....|N |  
-|----------------|-----
|________________|__________________________Q->front指向的位置即蛇头
|__________________________Q->rear指向的位置即蛇尾

------------------------
|A|C |N |N |.....|N |  
-|----------------|-----
|________________|__________________________Q->front指向的位置即蛇头
|__________________________Q->rear指向的位置即蛇尾

*/
}

//判断队列是否为空
int IsEmpty(LinkQueue Q){
if(Q.front->next==NULL) return(1);//队列为空,返回1
else return(0);
}

//前缀检索函数
int Prefix(char *q1,char *q2){
int flag=0;
for(;*q1!='\0';){
if(*q1==*q2) {q1++;q2++;}
else {flag=1;break;}
}
if(flag==0) return(1);//q1是q2的前缀
else return(0);
}

//打印队列的当前值
void PrintQueue(LinkQueue *Q){

//QueuePtr p=(QueuePtr)malloc(sizeof(QNode)+N+1);
QueuePtr p; //原句已经注释,不需要再申请新的结点空间,只需要一个指针指向已经存在的结点即可
p=(*Q).front->next; //此处如果上句不该,那么内存就泄漏了,只是将之前头结点指向的结点的地址赋给P
printf("Q=< ");
for(;p!=NULL;p=p->next){ //循环打印所有结点的数据
printf("%s ",p->qelem);
}
printf(">\n");
}

void main(){
LinkQueue Q; //声明队列
InitQueue(&Q); //初始化队列
char *a="0";
char *b="1";
EnQueue(&Q,a); //a入队列
EnQueue(&Q,b); //b入队列
while(!IsEmpty(Q)){ //判断队列是否为空
PrintQueue(&Q); //不为空则打印队列
//pointer指向标签ID组成的字符串:
//这里的标签ID个数、位数要分别与宏定义中的M、N保持一致。
char *pointer="000,001,101,110";
int count=0;
int i=0;
printf("发送请求%s\n",Q.front->next->qelem);
for(;i<M;i++,pointer+=(N+1)*sizeof(char)){
if(Prefix(Q. front->next->qelem,pointer)) count++;
}
QNode *pp=DeQueue(&Q);
printf("Update Q:");
PrintQueue(&Q);
char s[N+1];
strcpy(s,pp->qelem);
printf("响应的标签数count=%d\n",count);
if(count==0) {printf("没有标签响应\n");printf("\n");}
else if(count>=2){
EnQueue(&Q,strcat(pp->qelem,"0"));
EnQueue(&Q,strcat(s,"1"));
printf("冲突,重置Q:");
PrintQueue(&Q);
printf("\n");
}
else {printf("读标签\n");printf("\n");}
}
}
因为刚好在学数据结构,所以帮你注释一下吧,但是看到后面实在是写不下去了,这代码看得让人太蛋疼了,好的程序让人看的心情愉悦,但是这个程序让人心情看了不爽
温馨提示:答案为网友推荐,仅供参考
第1个回答  2014-10-15
要解释什么呢?这是一个队列定义以及一些基本操作的应用。本回答被网友采纳
相似回答