C/C++刷题预备——数据结构(五)循环队列和链式队列

队列

队列同样也是线性表的另外一种表现形式,只是区别在于队列要求尾部进入,头部弹出(即一端进,一端出,先进先出)

C/C++刷题预备——数据结构(五)循环队列和链式队列_第1张图片

根据队列的的特性,需要有两个偏移front对头指针和rear队尾指针,数据从队头进入,对尾弹出
C/C++刷题预备——数据结构(五)循环队列和链式队列_第2张图片
进队是rear自增,数组进数,指向的是所存元素的下一个空间,出队是front也是自增,不过这个时候他所指向需要出栈的数据位置。
由于这样操作,front和top都在增加,很容易超出数组的范围,所以使用循环队列来进行存储数据
C/C++刷题预备——数据结构(五)循环队列和链式队列_第3张图片

这个循环主要是依据多次进、出队列后的front和rear自增很大的数对线性表数组存储空间取余,得到在数组中的具体存储空间存放位置

不过有个小bug:不能让队满,不然无法判断是队满还是队空,换句话说:数据满的评判标注是rear+1 不能等于 front
接下来就是关于队列的相关代码
 

#include "stdio.h"

#define max 10

typedef struct node

{

    int data[max];

    int front, rear;

}Queue;

//初始化

void initQueue(Queue& l) {

    l.front = l.rear = 0;//这个0表示数组中的第一个元素

    printf("初始化结束");

}

//增加

bool Queueinsert(Queue& l,int a){

    if (l.rear+1 == l.front)//如果数据满了的话

    {

         printf("数据满了无法增加");

         return 0;

    }

    else

    {

         l.data[l.rear]= a;

         l.rear = (l.rear + 1) % max;

         return 1;

    }

}

int delQueue(Queue&l) {

    if (l.front==l.rear) {//注意:这里l.front==l.rear的时候表示已经没有元素了

         printf("我没有元素");

         return 0;

    }

    else

    {

         int a = l.data[l.front];

         l.front = (l.front + 1) % max;

         return a;

    }



}



int main() {

    Queue Queue1;

    //初始化

    initQueue(Queue1);

    //增

    bool b = Queueinsert(Queue1,3);

    //弹出

    int c = delQueue(Queue1);

    printf("ok");

    return 0;

}

除了使用上面的循环法,还能够使用链式存储法

#include "stdio.h"
typedef	struct node
{
	int data;
	struct node* next;
};
typedef struct
{
	struct node* front;
	struct node* rear;
}Queue;
//初始化队列
void initQueue(Queue& l)
{
	l.front = NULL;
	l.rear = NULL;
}
//初始化节点
void initnode(node& node1, int c) {
	node1.next = NULL;
	node1.data = c;
}
//判断是否是空队列
bool Queueempty(Queue& l) {
	if (l.rear == NULL) {
		return 1;
	}
	else
	{
		return 0;
	}
}
//新增
void insertnode(Queue& l, node& node1)
{
	if (Queueempty(l)) {
		l.rear = &node1;
		l.front= &node1;

	}
	else
	{
		node* p;
		p = l.rear;//让一个指针指向列表的第一个节点
		l.rear->next = &node1;
		l.rear = &node1;
	}
}
//删除
int delnode(Queue& l) {
	if (l.rear == NULL)
	{
		printf("空队列");
		return 0;
	}
	else
	{	int a;
		if (l.front->next == NULL){//如果就一个节点
			a = l.rear->data;
			l.front = l.rear = NULL;
			return a;
		}
		else
		{
			a = l.front->data;
			l.front = l.front->next;
			return a;
		}
	}
}


int main() { 
	//初始化一个队列
	Queue Queue1;
	initQueue(Queue1);
	//初始化节点
	node node1;
	node node2;
	initnode(node1, 1);
	initnode(node2, 2);
	//新增
	insertnode(Queue1, node1);

	insertnode(Queue1, node2);
	//删除
	int a = delnode(Queue1);
	int b= delnode(Queue1);
	printf("hello"); 
}

值得注意的是这里格外定义的头指针还有尾指针指向的节点均能够使用节点的data和next
要注意一下,这里的在函数中分配的栈指针在函数结束会被释放,如果用堆中分配的指针记得要free

你可能感兴趣的:(数据结构,c++)