假设以带头结点的单向循环链表表示队列,并且只设一个指针指向队尾元素结点(注意:不设头指针),试设计并验证相应的队列初始化、队列判空、入队列、出队列和遍历队列的源码
时间: 2024-04-21 21:04:21 浏览: 121
好的,下面是基于带头结点的单向循环链表表示队列的源码实现。
首先是队列的定义:
```c
// 队列结点结构体
typedef struct node {
int data; // 数据域
struct node* next; // 指针域
} Node;
// 队列结构体
typedef struct queue {
Node* rear; // 队尾指针
} Queue;
```
然后,我们需要实现以下操作:
1. 队列初始化
```c
// 初始化队列
void init(Queue* q) {
q->rear = (Node*) malloc(sizeof(Node));
q->rear->next = q->rear; // 指向自身
}
```
2. 队列判空
```c
// 判断队列是否为空
int is_empty(Queue* q) {
return q->rear == q->rear->next;
}
```
3. 入队列
```c
// 入队列
void enqueue(Queue* q, int x) {
Node* p = (Node*) malloc(sizeof(Node));
p->data = x;
p->next = q->rear->next;
q->rear->next = p;
q->rear = p;
}
```
4. 出队列
```c
// 出队列
int dequeue(Queue* q) {
if (is_empty(q)) {
printf("Queue is empty!\n");
return -1;
}
Node* front = q->rear->next->next; // 队头结点
int x = front->data;
q->rear->next->next = front->next;
if (q->rear == front) {
q->rear = q->rear->next; // 如果队列只有一个元素,出队列后队尾指针依然指向头结点
}
free(front);
return x;
}
```
5. 遍历队列
```c
// 遍历队列
void traverse(Queue* q) {
if (is_empty(q)) {
printf("Queue is empty!\n");
return;
}
Node* p = q->rear->next->next;
while (p != q->rear->next) {
printf("%d ", p->data);
p = p->next;
}
printf("\n");
}
```
验证代码:
```c
int main() {
Queue q;
init(&q);
printf("Queue is empty: %d\n", is_empty(&q)); // 1
enqueue(&q, 1);
enqueue(&q, 2);
enqueue(&q, 3);
printf("Queue is empty: %d\n", is_empty(&q)); // 0
traverse(&q); // 1 2 3
printf("Dequeue: %d\n", dequeue(&q)); // 1
printf("Dequeue: %d\n", dequeue(&q)); // 2
printf("Dequeue: %d\n", dequeue(&q)); // 3
printf("Dequeue: %d\n", dequeue(&q)); // Queue is empty! -1
printf("Queue is empty: %d\n", is_empty(&q)); // 1
return 0;
}
```
阅读全文