特别要注意的是,新设定两个指向链表结点的指针,rear和front,其中链表的结构体和指针的结构体定义如下
其中指针的结构体是无名结构体。有规定如果结构体中的成员,是一个指向结构体的指针,那么该结构体一定要是本结构体。但是这个无名结构体并不符合这个规定(问了老师我还是不明白为什么,虽然运行没问题,我把无名结构体又加了名字变成有名结构体还是运行没问题。。。)
老师甩了这个链接给我:无名结构体的一个妙用
本代码中存放数据用的是不带头结点的链表,好像头结点对于这里来说没什么用
//这个函数定义链表的头是front(用来pop出的),尾是rear(用来push进的)
#include <stdio.h>
#include <stdlib.h>
enum return_val {EMPTY_OK, EMPTY_NO, ENTER_OK, ENTER_NO, DELETE_OK, DELETE_NO, GET_OK, GET_NO};
typedef struct queue_data
{
int num;
struct queue_data * next;
} QueueNode;
typedef struct
{
QueueNode *front;
QueueNode *rear;
} LinkQueue;
void InitQueue(LinkQueue *Q)
{
Q->rear = Q->front = NULL;
}
int QueueEmpty(LinkQueue *Q)
{
if(Q->front == NULL)
{
return EMPTY_OK;
}
return EMPTY_NO;
}
int GetFront(LinkQueue *Q,int *num)
{
if(QueueEmpty(Q) == EMPTY_OK)
return GET_NO;
*num = Q->front->num;
return GET_OK;
}
int EnQueue(LinkQueue *Q,int num)
{
QueueNode *p;
if(create_node(&p) == 0)
{
return ENTER_NO;
}
p->num = num;
p->next = NULL;
if(Q->front == NULL)
{
Q->front = p;
Q->rear = p;
}
else
{
Q->rear->next = p;
Q->rear = p;
}
return ENTER_OK;
}
int DeQueue(LinkQueue *Q,int *num)
{
QueueNode *p;
if(QueueEmpty(Q) == EMPTY_OK)
{
return DELETE_NO;
}
p = Q->front;
*num = p->num;
Q->front = Q->front->next;
if(Q->front == NULL)
{
Q->rear = NULL;
}
free(p);
return DELETE_OK;
}
int is_malloc_ok(QueueNode *node)
{
if(node == NULL)
{
return 0;
}
else
{
return 1;
}
}
int create_node(QueueNode **node)
{
int count = 10;
do
{
*node = (QueueNode*)malloc(sizeof(QueueNode));
count--;
if(count == 0)
{
return 0;
}
}while(!is_malloc_ok(*node));
return 1;
}
void ReleaseQueue(LinkQueue *Q)
{
QueueNode *p;
while(Q->front != Q->rear)
{
p = Q->front;
Q->front = Q->front->next;
free(p);
}
p = Q->front;
Q->front = NULL;
Q->rear = NULL;
free(p);
}
int main()
{
LinkQueue Q;
int i;
int num;
InitQueue(&Q);
for(i = 0; i < 5; i++)
{
if(EnQueue(&Q,i + 1) == ENTER_NO)
{
printf("enter no!\n");
}
else
{
printf("enter ok! num is %d\n",i + 1);
}
}
for(i = 0; i < 3; i++)
{
if(GetFront(&Q,&num) == GET_NO)
{
printf("get no!\n");
}
else
{
printf("get ok! num is %d\n",num);
DeQueue(&Q,&num);
}
}
for(i = 0; i < 4; i++)
{
if(DeQueue(&Q,&num) == DELETE_NO)
{
printf("delete no!\n");
}
else
{
printf("delete ok! num is %d\n",num);
}
}
ReleaseQueue(&Q);
return 0;
}
小练:
要注意的问题:
- 用带头结点还是不带头结点的链表?
- 两个struct结构体里面的内容
- 新建Queue的操作,进队出队头指针尾指针的指向改变(特别是出队到队空的时候队尾指针指向要加上!!!)
- 老师的Queue创建时不是指针,好像还真用不到指针直接进入InitQueue,我还用了指针
- 出队入队的函数名怎么取的
#include <stdio.h>
#include <stdlib.h>
struct queue_data
{
int num;
struct queue_data *next;
};
typedef struct queue_data QueueNode;
struct queue
{
QueueNode *front;
QueueNode *rear;
};
typedef struct queue Queue;
int CreateNode(QueueNode **node)
{
*node = (QueueNode *)malloc(sizeof(QueueNode));
if(*node == NULL)
return 0;
return 1;
}
int CreateQueue(Queue **q)
{
*q = (Queue *)malloc(sizeof(Queue));
if(*q == NULL)
return 0;
(*q)->front = NULL;
(*q)->rear = NULL;
return 1;
}
int IsEmpty(Queue *q)
{
if(q->front == NULL)
return 1;
return 0;
}
int EnQueue(Queue *q, int num)
{
QueueNode *node;
if(!CreateNode(&node))
return 0;
node->num = num;
if(IsEmpty(q))
{
q->front = node;
q->rear = node;
}
else
{
q->rear->next = node;
q->rear = node;
}
node->next = NULL;
return 1;
}
int DeQueue(Queue *q, int *num)
{
QueueNode *node;
if(IsEmpty(q))
{
return 0;
}
node = q->front;
*num = node->num;
q->front = node->next;
free(node);
if(q->front == NULL)
{
q->rear = NULL;
}
}
int GetTop(Queue *q,int *num)
{
if(IsEmpty(q))
{
return 0;
}
*num = q->front->num;
return 1;
}
void EmptyQueue(Queue *q)
{
int num;
while(DeQueue(q, &num));
}
void ReleaseQueue(Queue **q)
{
EmptyQueue(*q);
free(*q);
}
int main()
{
Queue *q;
int i = 0, num = 1;
int temp;
CreateQueue(&q);
while(i < 10 && EnQueue(q, num))
{
i++;
num++;
if(GetTop(q, &temp))
{
printf("%d\n",temp);
}
}
printf("----------------\n");
while(DeQueue(q, &num))
{
printf("%d\n",num);
}
ReleaseQueue(&q);
return 0;
}