用指针实现队列

的情形相同,任何一种实现表的方法都可以用于实现队列。用指针实现队列得到的实际上是一个单链表。由于入队在队尾进行,所以用一个指针来指示队尾可以使入队操作不必从头到尾检查整个表,从而提高运算的效率。另外,指向队头的指针对于Front和Dequeue运算也是必要的。为了便于表示空队列,我们仍使用一个表头单元,将队头指针指向表头单元。当队头和队尾指针都指向表头单元时,表示队列为一个空队列。

用指针实现队列时,单元类型及队列类型可说明如下:

type

TPosition=^NodeType;

NodeType=record

          Element:ElementType;

          next:TPosition;

         end;

QueueType=record

           front,rear:TPosition;

          end;

其中front为队头指针,rear为队尾指针。图8是用指针表示队列的示意图。

图8 用指针实现队列

下面我们来讨论队列的5种基本运算。

函数 Front(Q)

功能

这是一个函数,函数值返回队列Q的队头元素。用一般的表运算可将Front(Q)表示为Retrieve(First(Q),Q)。

实现

Function Front(var Q:QueueType):ElementType;

begin

 if Empty(Q) then error('The queue is empty!')

             else return(Q.front^.next^.Element);

end;

说明

显然。

复杂性

显然为O(1)。

函数 Enqueue(x,Q)

功能

将元素x插入队列Q的队尾。此运算也常简称为将元素x入队。也可用一般的表运算将Enqueue(x,Q)表示为Insert(x,End(Q),Q)。

实现

Procedure Enqueue(x:ElementType;var Q:QueueType);

begin

 new(Q.rear^.next);

 Q.rear:=Q.rear^.next;

 Q.rear^.Element:=x;

 Q.rear^.next:=nil;

end;

说明

图9是该操作修改指针的示意图。

图9 入队操作

复杂性

显然为O(1)。

函数 Dequeue(Q)

功能

将Q的队头元素删除,简称为出队。用一般的表运算可将Dequeue(Q)表示为Delete(First(Q),Q)。

实现

Procedure Dequeue(var Q:QueueType);

var

p:TPosition;

begin

 if Empty(Q) then Error('The queue is empty!')

             else begin

                   p:=Q.front;

                   Q.front:=Q.front^.next;

                   dispose(p);

                  end;

end;

说明

图10是该操作修改指针的示意图。

图10 出队操作

复杂性

显然为O(1)。

函数 Empty(Q)

功能

这是一个函数,若Q是一个空队列,则函数值为true,否则为false。

实现

Function Empty(var Q:QueueType):Boolean;

begin

 return(Q.front=Q.rear);

end;

说明

当Q.front与Q.rear指向同一个结点单元时队列为空。

复杂性

显然为O(1)。

函数 MakeNull(Q)

功能

使队列Q成为空队列。

实现

Procedure MakeNull(var Q:QueueType);

begin

 Q.rear:=Q.front;

 while Q.front<>nil do

   begin

    Q.front:=Q.front^.next;

    dispose(Q.rear);

    Q.rear:=Q.front;

   end;

 new(Q.front);

 Q.front^.next:=nil;

 Q.rear:=Q.front;  

end;

说明

首先将Q中所有的结点内存释放,然后重新生成一个结点作为标头单元,并使Q.rear:=Q.front。

复杂性

若输入的队列Q中有n个结点,则复杂性为O(n)。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
下面是使用指针实现队列的示例代码(使用链表实现): ```c #include <stdio.h> #include <stdlib.h> // 定义队列节点结构 typedef struct Node { int data; struct Node* next; } Node; // 定义队列结构 typedef struct Queue { Node* front; Node* rear; } Queue; // 初始化队列 void initQueue(Queue* q) { q->front = NULL; q->rear = NULL; } // 判断队列是否为空 int isEmpty(Queue* q) { return (q->front == NULL); } // 入队操作 void enqueue(Queue* q, int data) { // 创建新节点 Node* newNode = (Node*)malloc(sizeof(Node)); newNode->data = data; newNode->next = NULL; if (isEmpty(q)) { // 队列为空,新节点为队头和队尾 q->front = newNode; q->rear = newNode; } else { // 将新节点加入队尾 q->rear->next = newNode; q->rear = newNode; } } // 出队操作 int dequeue(Queue* q) { if (isEmpty(q)) { printf("Queue is empty.\n"); return -1; // 返回一个特殊值表示出错 } // 取出队头节点数据并删除节点 int data = q->front->data; Node* temp = q->front; q->front = q->front->next; free(temp); // 如果队列为空,则重置队尾指针 if (q->front == NULL) { q->rear = NULL; } return data; } // 打印队列元素 void printQueue(Queue* q) { if (isEmpty(q)) { printf("Queue is empty.\n"); return; } Node* temp = q->front; while (temp != NULL) { printf("%d ", temp->data); temp = temp->next; } printf("\n"); } int main() { Queue q; initQueue(&q); enqueue(&q, 1); enqueue(&q, 2); enqueue(&q, 3); printf("Queue: "); printQueue(&q); int data = dequeue(&q); printf("Dequeued element: %d\n", data); printf("Queue after dequeue: "); printQueue(&q); return 0; } ``` 这个示例代码使用链表来实现队列,通过结构体指针 `front` 和 `rear` 分别指向队列的头部和尾部。入队操作通过创建新的节点并将其加入队尾,出队操作则取出队头节点并删除。`isEmpty()` 函数用于判断队列是否为空,`printQueue()` 函数用于打印队列中的元素。在 `main()` 函数中,我们进行了一些入队和出队操作,并打印队列的状态。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值