用C语言如果允许在循环队列的两端都可以进行插入和删除操作。构造一个循环队列,实现从队头入队,从队尾出队并输出。约定从队头入队时向下标小的方向发展,从队尾入队时则向下标大的方向发展。
时间: 2024-12-21 12:21:09 浏览: 3
在C语言中,要实现双向循环队列,我们需要扩展节点结构并且维护两个指针,一个`front`指向队头,另一个`rear`指向队尾。当需要在队头插入(入队)时,`front`指针会向前移动;在队尾插入(入队)时,`rear`指针会向后移动。同样地,队头出队(移除)时更新`front`,队尾出队(移除)时更新`rear`。这里是一个简单的实现:
首先,定义双向链表节点结构:
```c
typedef struct Node {
int data; // 节点存储的数据
struct Node* front; // 链接队首的指针
struct Node* rear; // 链接队尾的指针
} Node;
typedef struct DoubleCircularQueue {
Node* head;
Node* tail;
int size;
int capacity;
} DCircularQueue;
```
初始化队列:
```c
DCircularQueue* create_queue(int capacity) {
DCircularQueue* dq = malloc(sizeof(DCircularQueue));
dq->head = dq->tail = NULL;
dq->size = 0;
dq->capacity = capacity;
return dq;
}
```
入队操作(在队尾):
```c
void enqueue(DCircularQueue* dq, int value) {
if (dq->size == dq->capacity) {
// 队列满,无法再添加
printf("Queue is full.\n");
return;
}
Node* newNode = malloc(sizeof(Node));
newNode->data = value;
newNode->front = newNode->rear = dq->tail;
if (dq->tail != NULL) {
dq->tail->rear = newNode;
}
dq->tail = newNode;
dq->size++;
if (dq->front == NULL) {
dq->head = newNode;
}
}
```
出队操作(从队头或队尾):
```c
int dequeue(DCircularQueue* dq) {
if (dq->size == 0) {
// 队列为空
printf("Queue is empty.\n");
return -1; // 或者返回特殊值如INT_MIN
}
int value;
if (dq->front == dq->tail) {
// 队列只有一个元素,同时是队头和队尾
value = dq->front->data;
free(dq->front);
dq->front = dq->tail = NULL;
} else if (dq->front == dq->head) {
// 队头出队
value = dq->front->data;
Node* temp = dq->front;
dq->front = dq->front->front;
if (dq->front == NULL) {
dq->tail = NULL;
} else {
dq->front->rear = NULL;
}
free(temp);
dq->size--;
} else {
// 队尾出队
value = dq->tail->data;
Node* temp = dq->tail;
dq->tail = dq->tail->rear;
if (dq->tail == NULL) {
dq->head = NULL;
} else {
dq->tail->front = NULL;
}
free(temp);
dq->size--;
}
return value;
}
```
输出队列内容(假设队列非空):
```c
void print_queue(DCircularQueue* dq) {
for (Node* node = dq->head; node != NULL; node = node->front) {
printf("%d ", node->data);
}
printf("\n");
}
```
阅读全文