用循环链表表示队列

假设以带头结点的循环链表表示列队,并且只设一个指针指向队尾元素结点(注意不设头指针),试编写相应的置空队、判队空、入队和出队等算法。


该算法使用循环链表表示列队。

在算法中只设一个指向队尾元素的指针rear,在进行置空队,判队空等操作之前先将队列初始化;

置空队则是将队尾指针指向头结点;

入队则是在队尾插入元素,即在尾结点处插入元素,先申请一个新结点,再将新结点初始化并链入队列最后将尾指针移至新结点;

出队是先判断队列是否为空,不为空则继续接下来的出队操作。


该算法设计了个函数:

函数initQueue()用来初始化列队;

函数emptyQueue()用来将队置空;

函数enqueue()用来将元素链入列队;

函数delqueue()用来将元素出队;


算法流程图

 

源代码

/*********
date:2021-10-23
author:sy
version:1.0
Description: 以带头结点的循环链表表示列队,只设一个指针指向队尾元素(不设头指针) 
***********/
#include <stdio.h>
#include <stdlib.h>

typedef int elemType;
/*定义结点类型*/ 
typedef struct queuenode
{
	elemType data;
	struct queuenode *next;
}queuenode,*LinkQueue;

typedef struct
{
	LinkQueue rear;  //只设一个指向队尾元素的指针 
	int length;
}sqqueue;

/*初始化列队*/
void initQueue(sqqueue &Q)
{
	Q.rear=(LinkQueue)malloc(sizeof(Q));
	Q.rear->next=Q.rear;
}
/*置空队*/ 
int emptyQueue(sqqueue &Q)
{
	if(Q.rear->next==Q.rear)  //将队尾指针指向头结点 
		return 1;
	else
		return 0;
}
/*入队*/
int enqueue(sqqueue &Q,elemType e)
{   /*在尾结点处插入元素*/
	LinkQueue p;
	p=(LinkQueue)malloc(sizeof(Q));  //申请新结点 
	if(!p)
		return 0;
	/*初始化新结点并链入*/ 
	p->data=e;
	p->next=Q.rear->next;
	Q.rear->next=p;
	Q.rear=p;  //将尾指针移至新结点 
	return 1;
}
/*出队*/
int delqueue(sqqueue &Q,elemType &e)
{
	LinkQueue p;
	if(Q.rear->next==Q.rear)
		return 0;  //若队列为空返回0
	p=Q.rear->next->next;  //循环链表队列队尾指针下一结点(也即头结点)的下一结点(即队头指针)赋给p 
	e=p->data;  // 保存结点中的数据 
	Q.rear->next->next=p->next;  //摘下结点p 
	free(p);   //释放被删结点 
	return 1;
}

int main()
{
	sqqueue m;
	elemType num;
	initQueue(m);
	if(emptyQueue(m))
		printf("该队列目前为空!\n");
	else
		printf("该队列不为空!\n");
	for(int i=1;i<=10;i++)
		{
			if(enqueue(m,i))
			printf("元素%d成功入列!\n",i);
		}
	printf("\n\n");
	for(int j=1;j<=10;j++)
		{
			if(delqueue(m,num))
			printf("元素%d成功出列!\n",num);
		}
	if(emptyQueue(m))
		printf("该队列目前为空!\n");
	else
		printf("该队列不为空!\n");
	return 0;
}

函数delete()与函数free()函数 均可用来释放节点

Java可以使用以下代码来实现以带头结点的循环链表表示队列: ```java public class Queue<T> { private Node<T> head; private int size; public Queue() { head = new Node<>(null); head.next = head; size = 0; } public void enqueue(T item) { Node<T> newNode = new Node<>(item); newNode.next = head.next; head.next = newNode; size++; } public T dequeue() { if (isEmpty()) { throw new NoSuchElementException("Queue is empty"); } Node<T> nodeToRemove = head.next; head.next = nodeToRemove.next; size--; return nodeToRemove.data; } public T peek() { if (isEmpty()) { throw new NoSuchElementException("Queue is empty"); } return head.next.data; } public boolean isEmpty() { return size == 0; } public int size() { return size; } private static class Node<T> { T data; Node<T> next; Node(T data) { this.data = data; this.next = null; } } } ``` 在这个实现中,`Queue`类有一个`head`属性,它是一个带有`null`数据的空节点,用来作为循环链表的头结点。队列的大小由`size`属性记录。 `enqueue`方法将一个新节点插入到头结点之后,然后更新`size`。 `dequeue`方法从队列的头部删除一个节点,然后更新`size`并返回被删除节点的数据。如果队列为空,则抛出`NoSuchElementException`异常。 `peek`方法返回队列头部的节点的数据,但不删除该节点。如果队列为空,则抛出`NoSuchElementException`异常。 `isEmpty`方法检查队列是否为空。 `size`方法返回队列的大小。 `Node`是一个私有静态嵌套类,表示队列中的节点。每个节点都有一个`data`属性和一个指向下一个节点的`next`属性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值