队列的基本概念
队列 (Queue) :也是运算受限的线性表。是一种先进先出 (First In First Out ,简称 FIFO) 的线性表。只允许在表的一端进行插入,而在另一端进行删除。
队首 (front) :允许进行删除的一端称为队首。
队尾 (rear) :允许进行插入的一端称为队尾。

队列中没有元素时称为空队列。在空队列中依次加入元素 a 1 , a 2 , …, a n 之后, a 1 是队首元素, a n 是队尾元素。显然退出队列的次序也只能是 a 1 , a 2 , …, a n ,即队列的修改是依先进先出的原则进行的,如图 3-5 所示。

systemverilog清空队列delete c语言清空队列_#define

基本操作
1、创建新队列
2、判空
3、进队
4、出队
5、清空队
6、获得队头元素
7、遍历队
8、销毁队
9、队长
顺序队列
利用一组连续的存储单元 ( 一维数组 ) 依次存放从队首到队尾的各个元素,称为顺序队列。对于队列,和顺序栈相类似,也有动态和静态之分。这里介绍静态顺序队列.其类型定义如
下:

typedef int datatype;
#define MAX_QUEUE_SIZE 100
typedef struct queue
{ 
    datatype queue_array[MAX_QUEUE_SIZE];
    int front;
    int rear;
}sp_queue;

设立一个队首指针 front ,一个队尾指针rear ,分别指向队首和队尾元素。
◆ 初始化: front=rear =0。
◆ 入队:将新元素插入 rear 所指的位置,然后rear 加 1 。
◆ 出队:删去 front 所指的元素,然后加 1 并返回被删元素。
◆ 队列为空: front=rear 。
◆ 队满: rear = MAX_QUEUE_SIZE - 1 或front=rear 。

在非空队列里,队首指针始终指向队头元素,而队尾指针始终指向队尾元素的下一位置。顺序队列中存在“假溢出”现象。因为在入队和出队操作中,头、尾指针只增加不减小,致使被删除元素的空间永远无法重新利用。因此,尽管队列中实际元素个数可能远远小于数组大小,但可能由于尾指针巳超出向量空间的上界而不能做入队操作。该现象称为假溢出。如图 3-6 所示是数组大小为 5 的顺序队列中队首、队尾指针和队列中元素的变化情况。

systemverilog清空队列delete c语言清空队列_出队_02

代码实现:

1 /* 顺序队列接口定义头文件*/
  2 #define true 1
  3 #define false 0
  4 
  5 
  6 /* 队的最大长度 */
  7 #define MAX_QUEUE_SIZE 100
  8 /* 队列的数据类型 */
  9 typedef int datatype;
 10 
 11 /* 静态链的数据结构 */
 12 typedef struct queue{
 13     datatype sp_queue_array[MAX_QUEUE_SIZE];
 14     /* 队头 */
 15     int front;
 16     /* 队尾 */
 17     int rear;
 18 }sp_queue;
 19 
 20 
 21 /* 静态顺序链的接口定义 */
 22 
 23 
 24 /* 静态链的初始化 */
 25 sp_queue queue_init();
 26 
 27 /* 判断队列是否为空,若为空
 28  * 返回true
 29  * 否则返回false
 30 */
 31 int queue_empty(sp_queue q);
 32 
 33 
 34 /* 插入元素e为队q的队尾新元素 
 35  * 插入成功返回true
 36  * 队满返回false
 37 */
 38 int queue_en(sp_queue *q, datatype e);
 39 
 40 
 41 /* 队头元素出队
 42  * 用e返回出队元素,并返回true
 43  * 若队空返回false
 44 */
 45 int queue_de(sp_queue *q, datatype *e);
 46 
 47 /* 清空队 */
 48 void queue_clear(sp_queue *q);
 49 
 50 
 51 /* 获得队头元素
 52  * 队列非空,用e返回队头元素,并返回true
 53  * 否则返回false
 54 */
 55 int get_front(sp_queue, datatype *e );
 56 
 57 
 58 /* 获得队长 */
 59 int queue_len(sp_queue q);
 60 
 61 /* 遍历队 */
 62 void queue_traverse(sp_queue q, void(*visit)(sp_queue q));
 63 
 64 
 65 void visit(sp_queue s);
 66 
 67 
 68 /* 接口实现文件 */
 69 #include<stdio.h>
 70 #include<stdlib.h>
 71 #include"sp_queue.h"
 72 
 73 
 74 sp_queue queue_init()
 75 {
 76     sp_queue q;
 77     q.front = q.rear = 0;
 78     return q;
 79 }
 80 
 81 
 82 
 83 int queue_empty(sp_queue q)
 84 {
 85     return q.front == q.rear;
 86 }
 87 
 88 
 89 int queue_en(sp_queue *q, datatype e)
 90 {
 91     /* 队满 */
 92     if (q -> rear == MAX_QUEUE_SIZE)
 93         return false;
 94 
 95     /* 入队 */
 96     q -> sp_queue_array[q -> rear] = e;
 97     printf("q.sp_queue_array[%d]=%d\n", q -> rear, e);
 98     q -> rear += 1;
 99     return true;
100 
101 }
102 
103 
104 int queue_de(sp_queue *q, datatype *e)
105 {
106     /* 队空 */
107     if(queue_empty(*q))
108         return false;
109 
110     /* 出队 */
111     q -> rear -= 1;
112     *e = q -> sp_queue_array[q -> rear];
113     return true;
114 }
115 
116 
117 void queue_clear(sp_queue *q)
118 {
119     q -> front = q -> rear = 0;
120 }
121 
122 
123 int get_front(sp_queue q, datatype *e)
124 {
125     /* 队空 */
126     if(q.front == q.rear)
127         return false;
128 
129     /* 获取队头元素 */
130     *e = q.sp_queue_array[q.front];
131     return true;
132 }
133 
134 
135 int queue_len(sp_queue q)
136 {
137     return (q.rear - q.front);
138 }
139 
140 
141 void queue_traverse(sp_queue q, void (*visit)(sp_queue q))
142 {
143     visit(q);
144 }
145 
146 void visit(sp_queue q)
147 {
148     /* 队空 */
149     if (q.front == q.rear)
150         printf("队列为空\n");
151 
152     int temp = q.front;
153     while(temp != q.rear)
154     {
155         printf("%d ",q.sp_queue_array[temp]);
156         temp += 1;
157     }
158     printf("\n");
159 }
160 
161 
162 
163 int main()
164 {
165     sp_queue q = queue_init();
166     queue_en(&q, 1);
167     queue_en(&q, 2);
168     printf("length=%d\n", queue_len(q));
169     queue_en(&q, 3);
170     printf("length=%d\n", queue_len(q));
171     queue_en(&q, 4);
172     printf("length=%d\n", queue_len(q));
173     queue_en(&q, 5);
174     printf("length=%d\n", queue_len(q));
175     queue_en(&q, 6);
176     printf("length=%d\n", queue_len(q));
177     queue_traverse(q,visit);
178     datatype *e = (datatype *)malloc(sizeof(*e));
179     queue_de(&q,e);
180     printf("queue_de(),e=%d length=%d\n", *e, queue_len(q));
181     queue_traverse(q, visit);
182     queue_clear(&q);
183     queue_traverse(q, visit);
184     printf("length:%d\n", queue_len(q));
185 }

队列的链式表示和实现

队列的链式存储结构简称为链队列,它是限制仅在表头进行删除操作和表尾进行插入操作的单链表。需要两类不同的结点:数据元素结点,队列的队 
首指针和队尾指针的结点,如图 3-8 所示。 

systemverilog清空队列delete c语言清空队列_结点_03

 

 数据元素结点类型定义:

typedef struct q_node{
    datatype data;
    struct q_node *next;
}q_node;

指针结点类型:

typedef struct {
    q_node *front;
    q_node *rear;   
}link_queue;

链队运算及指针变化

链队的操作实际上是单链表的操作,只不过是删除 
在表头进行,插入在表尾进行。插入、删除时分别修改 
不同的指针。链队运算及指针变化如图 3-9 所示。

systemverilog清空队列delete c语言清空队列_#define_04

 

代码实现:

1 /* 链式栈接口的定义头文件 */
  2 #define true 1
  3 #define false 0
  4 
  5 
  6 /* 队列的数据类型 */
  7 typedef int datatype;
  8 
  9 /* 静态链的数据结构 */
 10 typedef struct q_node{
 11     datatype data;
 12     struct q_node *next;
 13 }q_node,*link_node;
 14 
 15 typedef struct l_queue{
 16     /* 队头指针 */
 17     q_node *front;
 18     /* 队尾指针 */
 19     q_node *rear;
 20 }*link_queue;
 21 
 22 
 23 /* 静态顺序链的接口定义 */
 24 
 25 
 26 /* 静态链的初始化 */
 27 link_queue queue_init();
 28 
 29 /* 判断队列是否为空,若为空
 30  * 返回true
 31  * 否则返回false
 32 */
 33 int queue_empty(link_queue q);
 34 
 35 /* 插入元素e为队q的队尾新元素 
 36  * 插入成功返回true
 37  * 队满返回false
 38 */
 39 int queue_en(link_queue q, datatype e);
 40 
 41 
 42 /* 队头元素出队
 43  * 用e返回出队元素,并返回true
 44  * 若队空返回false
 45 */
 46 int queue_de(link_queue q, datatype *e);
 47 
 48 /* 清空队 */
 49 void queue_clear(link_queue q);
 50 
 51 /* 销毁队 */
 52 void queue_destroy(link_queue q);
 53 
 54 /* 获得队头元素
 55  * 队列非空,用e返回队头元素,并返回true
 56  * 否则返回false
 57 */
 58 int get_front(link_queue q, datatype *e );
 59 
 60 
 61 /* 获得队长 */
 62 int queue_len(link_queue q);
 63 
 64 /* 遍历队 */
 65 void queue_traverse(link_queue q, void(*visit)(link_queue q));
 66 
 67 
 68 void visit(link_queue q);
 69 
 70 
 71 
 72 /* 接口的实现文件 */
 73 #include<stdio.h>
 74 #include<stdlib.h>
 75 #include"lp_queue.h"
 76 
 77 
 78 
 79 link_queue queue_init()
 80 {
 81     /* 新建头结点 */
 82     link_node new_node = (link_node)malloc(sizeof(q_node));
 83     new_node -> next = NULL;
 84     /* 指针结点 */
 85     link_queue q = (link_queue)malloc(sizeof(*q));
 86     q -> front = q -> rear = new_node;
 87     return q;
 88 }
 89 
 90 
 91 int queue_empty(link_queue q)
 92 {
 93     return q -> front == q -> rear;
 94 }
 95 
 96 
 97 int queue_en(link_queue q, datatype e)
 98 {
 99     /* 新建数据结点 */
100     link_node new_node = (link_node)malloc(sizeof(q_node));
101     /* 内存分配失败 */
102     if(!new_node)
103         return false;
104     new_node -> data = e;
105     q -> rear -> next = new_node;
106     q -> rear = new_node;
107     return true;
108 }
109 
110 int queue_de(link_queue q, datatype *e)
111 {
112     /* 队列为空 */
113     if (q -> front == q -> rear)
114         return false;
115 
116     *e = q -> front -> next -> data;
117     link_node temp = q -> front -> next;
118     q -> front -> next = temp -> next;
119     /* 防止丢失尾指针 */
120     if (temp == q.rear -> next)
121         q -> rear = q -> front; 
122     free(temp);
123     temp = NULL;
124     return true;
125 }
126 
127 void queue_clear(link_queue q)
128 {
129     /* 头结点 */
130     link_node head = q -> front -> next;
131     head -> next = NULL;
132     q -> front = q -> rear = head;
133     /* 第一个结点 */
134     link_node temp = head -> next;
135     while(temp)
136     {
137         link_node p = temp;
138         temp = p -> next;
139         free(p);
140         p = NULL;
141     }
142 }
143 
144 
145 void queue_destroy(link_queue q)
146 {
147     queue_clear(q);
148     free(q);
149     q = NULL;
150 }
151 
152 
153 int get_front(link_queue q, datatype *e)
154 {
155     /* 队为空 */
156     if (q -> front == q -> rear)
157         return false;
158 
159     *e = q -> front -> next -> data;
160     link_node temp = q -> front -> next;
161     q -> front -> next = temp -> next;
162     free(temp);
163     temp = NULL;
164     return true;
165 }
166 
167 
168 int queue_len(link_queue q)
169 {
170     /* 头结点 */
171     link_node p = q -> front -> next;
172     /* 计数器 */
173     int count = 0;
174     while(p)
175     {
176         count += 1;
177         p = p -> next;
178     }
179     return count;
180 }
181 
182 
183 void queue_traverse(link_queue q, void(*visit)(link_queue q))
184 {
185     visit(q);
186 }
187 
188 void visit(link_queue q)
189 {
190     /* 头结点 */
191     link_node p = q -> front -> next;
192     if(!p)
193     {
194         printf("队列为空");
195     }
196     while(p)
197     {
198         printf("%d ", p -> data);
199         p = p -> next;
200     }
201     printf("\n");
202 }
203 
204 int main()
205 {
206     link_queue q = queue_init();
207     queue_en(q, 1);
208     queue_en(q, 2);
209     printf("length=%d\n", queue_len(q));
210     queue_en(q, 3);
211     printf("length=%d\n", queue_len(q));
212     queue_en(q, 4);
213     printf("length=%d\n", queue_len(q));
214     queue_en(q, 5);
215     printf("length=%d\n", queue_len(q));
216     queue_en(q, 6);
217     printf("length=%d\n", queue_len(q));
218     queue_traverse(q,visit);
219     datatype *e = (datatype *)malloc(sizeof(*e));
220     queue_de(q,e);
221     printf("queue_de(),e=%d length=%d\n", *e, queue_len(q));
222     queue_traverse(q, visit);
223     queue_clear(q);
224     queue_traverse(q, visit);
225     printf("length:%d\n", queue_len(q));
226 }