特別要注意的是,新設定兩個指向鏈表結點的指針,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;
}