数据结构学习笔记——队列

队列的定义

队列的顺序存储结构和基本运算的实现

类型声明

初始化队列

销毁队列

判断队列是否为空

进队列

出队列

环形队列

基本运算

初始化

销毁

判断队列是否为空

进队列

出队列

链队

链队的基本运算

初始化

销毁

判断是否为空

进队列

出队列

不带头结点只有一个尾节点指针的循环单链表存储队列

基本运算

初始化

进队

出队

判断是否为空

对列的定义:
一种操作受限制的线性表,仅允许在表的一端进行插入操作,在另一端进行删除操作,把进行插入操作的一端叫做队尾,进行删除操作的叫做队首。删除元素叫做出队,插进元素叫做入队。
在这里插入图片描述
队列的顺序存储结构以及基本运算的实现:
采用顺序表的存储结构,并用两个整形变量来反映队列中元素的变化,它们分别存储队首元素和对尾元素的下标位置,分别称作队首指针和队尾指针。采用顺序存储结构的队列称作顺序队

基本运算:
类型声明:

#define maxsize 100
typedef int Elemtype;
typedef struct
{
	Elemtype data[maxsize];
	int front,rear;
} SqQueue;

初始化队列:

SqQueue* InitQueue(SqQueue *q)
{
	q = (SqQueue *)malloc(sizeof(SqQueue));
	q -> front = q -> rear = -1;
	return q;
}

在这里插入图片描述
销毁队列:
直接释放指向队列那个指针所指向的存储空间即可。

void DestroyQueue(SqQueue *q)
{
	free(q);
}

在这里插入图片描述
判断队列是否为空:
只要看队首元素是否和队尾元素相等。

_Bool QueueEmpty(SqQueue *q)
{
	return (q -> front == q -> rear);
}

进队列:
在队列不满的情况下将尾指针增1,然后将元素e插入到该位置。

_Bool enQueue(SqQueue *q,Elemtype e)
{
	if (q -> rear == maxsize -1) return 0;
	else
	{
		q -> rear ++;
		q -> data[q -> rear] = e;
		return 1;
	}
}

出队列:
在队列不为空的情况下队首指针增1,然后将该位置的元素赋给e。

_Bool deQueue(SqQueue *q,Elemtype e)
{
	if (q -> front == q -> rear) return 0;
	else
	{
		q -> front ++;
		e = q -> data[q -> front];
		return 1;
	}
}

环形队列:
在逻辑上将队首与队尾结合起来。
为了实现从队首到队尾的过渡,指针循环增1的算法应采用取余算法:

front = (front +1)%maxsize;
rear = (rear +1)%maxsize;

环形队列的队首和队尾指针开始都设置为0.
队空的条件:队首指针等于队尾指针。
队满的条件:如果把整个数组全都装满元素定义为队满,那么队满时两个指针也会相等,这就无法和队空相区分,所以我们就把队满定义为队尾指针加一再对maxsize取余数,所得若等于队首指针,那么就队满。也就是队尾指针所指的元素紧挨着队首元素所指向的空间,但是队首元素那里不放置元素。在这里插入图片描述
基本运算:
初始化队列:

void InitQueue(SqQueue *p)
{
	p = (SqQueue *)malloc(sizeof(SqQueue));
	p -> front = p -> rear = 0;
}

销毁队列:

void DestroyQueue(SqQueue *p)
{
	free(p);
}

判断队列是否为空:

_Bool QueueEmpty(SqQueue *p)
{
	return (p -> front == p -> rear);
}

进队列:

_Bool enQueue(SqQueue *q,Elemtype e)
{
	if ((q -> rear + 1)%maxsize == q -> front) return 0;
	else
	{
		q -> rear = (q -> rear +1)%maxsize;
		q -> data[q -> rear] = e;
		return 1;
	}
}

出队列:

_Bool deQueue(SqQueue *q,Elemtype *e)
{
	if (q -> front == q -> rear) return 0;
	else
	{
		q -> front ++;
		*e = q -> data[q -> front];
		return 1;
	}
}

链队:
采用链表存储结构的队列。

在这里插入图片描述
基本运算:
链队数据结点的类型声明:
数据结点:数据域+指针域

typedef struct qnode
{
	Elemtype data;
	struct qnode *next;
} DataNode;

链队结点:队首指针+队尾指针

typedef struct
{
	DataNode *front;
	DataNode *rear;
} LinkQuNode;

初始化队列:
就是创造一个空队,也就是front和rear均为NULL的链队结点。

void InitLinkQueue(LinkQuNode *p)
{
	p = (LinkQuNode *)malloc(sizeof(LinkQuNode));
	p -> front = NULL;
	p -> rear = NULL;
}

销毁队列:
销毁链队结点和数据结点。

void DestroyLinkQueue(LinkQuNode *q)
{
	DataNode *pre = p -> front;
	DataNode *p = pre -> next;
	if (pre != NULL)
	{
		while(p!= NULL)
		{
			free(pre);
			pre = p;
			p = p -> next;
		}
		free(pre);
	}
	free(q);
}

判断队列是否为空:
判断指针之一是否指向元素即可。

_Bool LinkQuEmpty(LinkQuNode *p)
{
	return (p -> front == NULL);
}

进队列:
创建数据结点,赋值,在rear后面插入,让rear指向这个结点。

void enLinkQueue(LinkQuNode *p,Elemtype e)
{
	DataNode *s;
	s = (DataNode *)malloc(sizeof(DataNode));
	s -> data = e;
	s -> next = NULL;
	if (p -> rear == NULL) p -> front = p -> rear = s;
	else
	{
		p -> rear -> next = s;
		p -> rear = s;
	}
}

出队列:
若是空队列,返回错误;只有一个结点,标记结点,设置双指针为NULL;否,则取值,标记,移位,释放。

_Bool deLinkQueue(LinkQuNode *p,Elemtype *e)
{
	DataNode *t;
	if (p -> front == NULL) return 0;
	else if(p -> front == p -> rear)
	{
		*e = p -> front -> data;
		t = p -> front;
		p -> front = p -> rear = NULL;
		free(t);
		return 1;
	}
	else
	{
		*e = p -> front -> data;
		t = p -> front;
		p -> front = t -> next;
		free(t);
		return 1;
	}
}

只有尾结点的循环单链表:
与链队相比,此种队列少了队首指针,或者是说队首指针在队尾结点的指针域里面。
在这里插入图片描述
基本运算:
初始化:
一个空指针。

typedef int Elemtype;
typdef struct Node
{
	Elemtype data;
	struct Node *next;
} LinNode;

void InitQueue(LinkNode *p)
{
	p = NULL;
}

进队:
若队列为空,则将结点变成循环链表后将rear指向这个结点;否则先让这个结点指向队首元素,然后变成队尾元素,最后将rear指向这个结点。两种情况就是把链表重新变成循环链表的方法不一样,其他的都一样,所以可以将这两种情况融合。在这里插入图片描述

void enQueue(LinkNode *p,Elemtype e)
{
	LinkNode *s;
	s = (LinkNode *)malloc(sizeof(LinkNode));
	s -> data = e;
	s -> next = NULL;
	if (p == NULL) s -> next = s;
	else
	{
		s -> next = rear -> next;
		rear -> next = s;
	}
	rear = s;
}

出队:

_Bool enQueue(LinkNode *p,Elemtype *e)
{
	if (p == NULL) return 0;
	else if(p -> next == p)
	{
		free(p);
		p = NULL;
	}
	else
	{
		LinkNode *t;
		t = p -> next;
		*e = t -> data;
		p -> next = t -> next;
		free(t);
	}
	return 1;
}

判断是否为空:

_Bool QueueEmpty(LinkNode *p)
{
	return(p == NULL);
}
  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值