1.队列的定义:
队列(Queue)是另一种限定性的线性表,它只允许在表的另一端插入元素,而在另一端删除元素,
所以队列具有先进先出的特性(First In First Out,FIFO)。其中,允许插入的一端称为队尾(rear),允许删除的端称为队头(front)。
例: 假设队列Q = (a1, a2, a3, ..., an),则队头(front)是a1,队尾(rear)是an。
入队是按照a1, a2, a3, ..., an的顺序入队的, 出队也是按照这个顺序出队的。
2.队列的实现:
队列有两种储存方式,即顺序表示和链式表示。这里主要介绍链式表示,即链队列。用链表表示的队列简称链队列。
为了方便出队,这里采用带头结点的链表结构,并设置一个队头指针(front)始终指向头结点,一个队尾指针(rear)始终指向最后一个结点。
控队列的队头指针和队尾指针均指向头结点。通常将队头指针和队尾指针封装在一个结构体中。
3.队列的相关操作:
(0).定义结构体 & 定义宏:
链队列结点的结构体定义如下:
typedef struct QueueNode{
ElementType queue_date;
struct QueueNode *next;
}Node;
队头指针和队尾指针的封装如下:
typedef struct QueueLink{
Node *front;
Node *rear;
}Link;
定义宏:
#define true 1
#define false 0
(1).链队初始化:
int InitQueue(Link *Q){
Q->front = (Node*)malloc(sizeof(Node));
if(Q->front == NULL)
return false;
Q->rear = Q->front;
Q->front->next = NULL;
return true;
}
(2).判断队空:
int IsEmpty(Link *Q){
if(Q->front == Q->rear)
return true;
else
return false;
}
(3).元素入队:
int EnterQueue(Link *Q, ElementType x){
Node *s;
s = (Node*)malloc(sizeof(Node));
if(s == NULL)
return false;
s->date = x;
s->next = NULL;
Q->rear->next = s;
Q->rear = s;
return true;
}
(4).元素出队:
int PopQueue(Link *Q, ElementType *x){
if(IsEmpty(Q))
return false;
Node *p;
p = (Node*)malloc(sizeof(Node));
if(p == NULL)
return false;
p = Q->front->next;
Q->front->next = p->next;
*x = p->date;
return true;
}
4.队列的应用之一:二叉树的层次遍历(假设树中元素是字符型) 全部参考代码如下:
#include<stdio.h>
#include<stdlib.h>
/*二叉树结点结构体的定义*/
typedef struct TreeNode{
char tree_date;
struct TreeNode *Lchild;
struct TreeNode *Rchild;
}Tree;
/*队列结点结构体的定义*/
typedef struct QueueNode{
Tree *queue_date;
struct QueueNode *next;
}Node;
/*封装队头指针和队尾指针*/
typedef struct QueueLink{
Node *front;
Node *rear;
}Link;
/*建立二叉树*/
void EstBiTree(Tree **root){
char c;
scanf("%c", &c);
getchar();
if(c == '#'){
*root = NULL;
return;
}
*root = (Tree*)malloc(sizeof(Tree));
(*root)->tree_date = c;
printf("Enter left child of %c:\n", c);
EstBiTree(&((*root)->Lchild));
printf("Enter right child of %c:\n", c);
EstBiTree(&((*root)->Rchild));
}
/*初始化队列*/
void InitQueue(Link **Q){
(*Q)->front = (Node*)malloc(sizeof(Node));
if((*Q)->front == NULL){
printf("InitQueue: malloc failed!\n");
return;
}
(*Q)->rear = (*Q)->front;
(*Q)->front->next = NULL;
}
/*判断队空*/
int IsEmpty(Link *Q){
if(Q->rear == Q->front)
return 1;
else
return 0;
}
/*元素入队*/
void EnterQueue(Link **Q, Tree *in_root){
Node *s;
s = (Node*)malloc(sizeof(Node));
if(s == NULL){
printf("EnterQueue: malloc failed!\n");
return;
}
s->queue_date = in_root;
s->next = NULL;
(*Q)->rear->next = s;
(*Q)->rear = s;
}
/*元素出队*/
void PopQueue(Link **Q, Tree **out_root){
if(IsEmpty(*Q))
return;
Node *p;
p = (*Q)->front->next;
(*Q)->front->next = p->next; //队头元素出队
if((*Q)->rear == p)
(*Q)->rear = (*Q)->front;
*out_root = p->queue_date;
free(p);
}
/*层次遍历二叉树*/
void CengCi(Tree *root){
if(root == NULL)
return;
Tree *out_root = (Tree*)malloc(sizeof(Tree));
Link *Q = (Link*)malloc(sizeof(Link));
InitQueue(&Q);
EnterQueue(&Q, root);
while(!IsEmpty(Q)){
PopQueue(&Q, &out_root);
printf("%c ", out_root->tree_date);
if(out_root->Lchild)
EnterQueue(&Q, out_root->Lchild);
if(out_root->Rchild)
EnterQueue(&Q, out_root->Rchild);
}
}
/*主函数:建立二叉树并进行层次遍历*/
void main(){
Tree *bt;
EstBiTree(&bt);
printf("result is:\n");
CengCi(bt);
printf("\n");
}
5.ps:新手的第一篇博客,如有错误,不吝指教!谢谢!