Data structure - implementation of sequential queue and chained queue

Table of contents

1. Concept

1. Definition of queue

2. Team leader

3. The end of the team

2. Interface

1. Writable interface

1) Data enqueue

2) Data dequeuing

3) Clear the queue

2. Read-only interface

1) Get team leader data

2) Get the number of queue elements

3) Empty judgment of queue

3. Queue sequence table implementation

1. Data structure definition

2. Initialize the creation queue

3. Determine whether the queue is full

4. Determine whether the queue is empty

5. Join the team

6. Leave the team

7. Print queue

8. Queue sequence table implementation source code

4. Queue linked list implementation

1. Data structure definition

2. Initialize the creation queue

3. Determine whether the queue is empty

4. Join the team

5. Leave the team

6. Print queue

7. Queue linked list implementation source code


1. Concept

1. Definition of queue

  A queue is a linear list  limited   to  insertions at one end and deletions at  the   other  end . The queue  is also called a First In First Out (First In First Out) linear table, or FIFO for short.
  

2. Team leader

  The end that allows element deletion is called  the head of the queue . As shown below:

3. The end of the team

  The end that allows element insertion is called  the tail of the queue . As shown below:

2. Interface

1. Writable interface

1) Data enqueue

  The insertion operation of the queue is called  enqueue . It is  the process of inserting data elements  from  the end of the queue  , as shown in the figure, which represents  the process of inserting  two data (green and blue):

2) Data dequeuing

  The deletion operation of the queue is called  dequeuing . It is  the process of deleting the first  element of the team, as shown in the figure, which represents  the process of deleting  two pieces of data (red and orange) in sequence:

3) Clear the queue

  The clearing operation of the queue is  the process of dequeuing until the queue is empty. When  the head  and  tail of the queue  coincide, it means that the tail of the queue is empty, as shown in the figure:

2. Read-only interface

1) Get team leader data

  For a queue, only  the head  data can be obtained, and other data is generally not supported.

2) Get the number of queue elements

  The number of queue elements is generally stored in an additional variable, which is increased by one when entering the queue  and decreased by one when dequeuing  . In this way, there is no need to traverse the entire queue when obtaining queue elements. Obtain the number of queue elements with O(1) time complexity.

3) Empty judgment of queue

  When the number of queue elements is zero, it is an  empty queue , and dequeue operations  are not allowed for  empty queues  .

3. Queue sequence table implementation

1. Data structure definition

For the sequence table, which is represented as an array in C language  ,  before defining the queue  , we need to consider the following points:
  1) The storage method of the queue data, and the data type of the queue data;
  2) The size of the queue;
  3) Team head pointer;
  4) Team tail pointer;

We can define a  queue structure ,  and  the C language implementation is as follows:

#define MAXSIZE 10
typedef int datatype;

typedef struct seqqueue{
	datatype data[MAXSIZE];
	int front,rear;
}seq_queue,*seq_pqueue;

2. Initialize the creation queue

The first invisible parameter is implemented in C language as follows:

seq_pqueue init1_seqqueue(void)
{
	seq_pqueue q;
	q=(seq_pqueue)malloc(sizeof(seq_queue));
	if(q==NULL)
	{
		perror("malloc");
		exit(-1);
	}
	q->front=q->rear=MAXSIZE-1;

	return q;
}

The second type of formal parameters is implemented in C language as follows:

void init_seqqueue(seq_pqueue *Q)
{
	*Q=(seq_pqueue)malloc(sizeof(seq_queue));
	if((*Q)==NULL)
	{
		perror("malloc");
		exit(-1);
	}
	(*Q)->front=(*Q)->rear=MAXSIZE-1;
	
	return;
}

3. Determine whether the queue is full

The C language implementation is as follows:

bool is_full_seqqueue(seq_pqueue q)
{
	if((q->rear+1)%MAXSIZE == q->front)
		return true;
	else
		return false;
}

4. Determine whether the queue is empty

The C language implementation is as follows:

bool is_empty_seqqueue(seq_pqueue q)
{
	if(q->rear == q->front)
		return true;
	else
		return false;
}

5. Join the team

The C language implementation is as follows:

bool in_seqqueue(datatype data,seq_pqueue q)
{
	//判断队列是否满
	if(is_full_seqqueue(q)){
		printf("队列已满!\n");
		return false;
	}

	//入队
	q->rear=(q->rear+1)%MAXSIZE;
	q->data[q->rear]=data;
	return true;
}

6. Leave the team

The C language implementation is as follows:

bool out_seqqueue(seq_pqueue q,datatype *D)
{
	//判断队列是否空
	if(is_empty_seqqueue(q)){
		printf("队列已空!\n");
		return false;
	}

	//出队
	q->front=(q->front+1)%MAXSIZE;
	*D=q->data[q->front];

	return true;
}

7. Print queue

The C language implementation is as follows:

void show_seqqueue(seq_pqueue q)
{
	int i;
	if(is_empty_seqqueue(q))
		return;
	//非空时,从对头打印到队尾
	for(i=(q->front+1)%MAXSIZE;i!=(q->rear+1)%MAXSIZE;i=(i+1)%MAXSIZE)
	{
		printf("%d\t",q->data[i]);
	}
	printf("\n");
}

8. Queue sequence table implementation source code

seqqueue.h

#ifndef __SEQQUEUE_H__
#define __SEQQUEUE_H__

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>

#define MAXSIZE 10
typedef int datatype;

typedef struct seqqueue{
	datatype data[MAXSIZE];
	int front,rear;
}seq_queue,*seq_pqueue;

extern seq_pqueue init1_seqqueue(void);
extern void init_seqqueue(seq_pqueue *Q);
extern bool is_full_seqqueue(seq_pqueue q);
extern bool is_empty_seqqueue(seq_pqueue q);
extern bool in_seqqueue(datatype data,seq_pqueue q);
extern bool out_seqqueue(seq_pqueue q,datatype *D);
extern void show_seqqueue(seq_pqueue q);

#endif

seqqueue.c

#include "seqqueue.h"

seq_pqueue init1_seqqueue(void)
{
	seq_pqueue q;
	q=(seq_pqueue)malloc(sizeof(seq_queue));
	if(q==NULL)
	{
		perror("malloc");
		exit(-1);
	}
	q->front=q->rear=MAXSIZE-1;

	return q;
}

void init_seqqueue(seq_pqueue *Q)
{
	*Q=(seq_pqueue)malloc(sizeof(seq_queue));
	if((*Q)==NULL)
	{
		perror("malloc");
		exit(-1);
	}
	(*Q)->front=(*Q)->rear=MAXSIZE-1;
	
	return;
}

//判断队列是否满
bool is_full_seqqueue(seq_pqueue q)
{
	if((q->rear+1)%MAXSIZE == q->front)
		return true;
	else
		return false;
}

//入队
bool in_seqqueue(datatype data,seq_pqueue q)
{
	//判断队列是否满
	if(is_full_seqqueue(q)){
		printf("队列已满!\n");
		return false;
	}

	//入队
	q->rear=(q->rear+1)%MAXSIZE;
	q->data[q->rear]=data;
	return true;
}

//判断队列是否空
bool is_empty_seqqueue(seq_pqueue q)
{
	if(q->rear == q->front)
		return true;
	else
		return false;
}

//出队
bool out_seqqueue(seq_pqueue q,datatype *D)
{
	//判断队列是否空
	if(is_empty_seqqueue(q)){
		printf("队列已空!\n");
		return false;
	}

	//出队
	q->front=(q->front+1)%MAXSIZE;
	*D=q->data[q->front];

	return true;
}

void show_seqqueue(seq_pqueue q)
{
	int i;
	if(is_empty_seqqueue(q))
		return;
	//非空时,从对头打印到队尾
	for(i=(q->front+1)%MAXSIZE;i!=(q->rear+1)%MAXSIZE;i=(i+1)%MAXSIZE)
	{
		printf("%d\t",q->data[i]);
	}
	printf("\n");
}

test.c

#include "seqqueue.h"
/* 用循环队列实现如下功能:
 * 用户从键盘输入整数,程序将其入队;
 * 用户从键盘输入字母,程序将队头元素出队;
 * 并在每一次出队和入队之后打印队列元素。
 */
int main(int argc, const char *argv[])
{
	seq_pqueue q;
	datatype data,t,ret;
	
	init_seqqueue(&q);

	while(1)
	{
		printf("请输入一个整数或字符:");
		ret=scanf("%d",&data);
		
		//输入整数时,入队
		if(ret == 1)
		{
			if(in_seqqueue(data,q))
				show_seqqueue(q);
		}
		else
		{
			//输入为字符时
			if(out_seqqueue(q,&t))
			{
				printf("out:%d\n",t);
				show_seqqueue(q);
			}
			//清空输入缓冲区
			while(getchar()!='\n');
		}
	}
	return 0;
}

Makefile

CC = gcc
CFLAGS = -o0 -g -Wall

SRC=seqqueue.c test.c
OBJS=test

$(OBJS):$(SRC)
	$(CC) $(CFLAGS) -o $@ $^

.PHONY:clean
clean:
	rm -rf $(OBJS) *.o
  • "-o0" means the optimization level is 0, that is, optimization is turned off. This will result in a larger executable file, but can be easily debugged.
  • "-g" means generating debugging information so that you can view the values ​​of variables, function call stacks and other information when debugging the program.
  • "-Wall" means to enable all warnings, and the compiler will display all possible warning messages to help developers find potential problems.

Compilation result test:

4. Queue linked list implementation

1. Data structure definition

For linked lists,  before defining the queue  , we need to consider the following points:
  1) The storage method of the queue data, and the data type of the queue data;
  2) The size of the queue;
  3) The head pointer of the queue;
  4) The tail pointer of the queue ;

We can define a  queue structure ,  and  the C language implementation is as follows:

typedef int datatype;

typedef struct linkqueuenode{ 
	datatype data;                    /* 数据域 */
	struct linkqueuenode *next;       /* 指针域 */
}linkqueue_node,*linkqueue_pnode;

typedef struct linkqueue{
	linkqueue_pnode front,rear;       /* 链队列指针 */
}link_queue,*link_pqueue;

2. Initialize the creation queue

The C language implementation is as follows:

void init_linkqueue(link_pqueue *Q)
{
	//申请front和rear的空间
	*Q=(link_pqueue)malloc(sizeof(link_queue));
	if((*Q)==NULL)
	{
		perror("malloc");
		exit(-1);
	}
	//申请头结点空间
	(*Q)->front=(linkqueue_pnode)malloc(sizeof(linkqueue_node));
	if((*Q)->front==NULL)
	{
		perror("malloc");
		exit(-1) ;
	}

	(*Q)->front->next=NULL;
	(*Q)->rear=(*Q)->front;

	return;
}

3. Determine whether the queue is empty

The C language implementation is as follows:

bool is_empty_linkqueue(link_pqueue q)
{
	if(q->rear == q->front)
		return true;
	else
		return false;
}

4. Join the team

The C language implementation is as follows:

bool in_linkqueue(datatype data,link_pqueue q)
{
	linkqueue_pnode  new;

	//申请数据结点空间
	new=(linkqueue_pnode)malloc(sizeof(linkqueue_node));
	if(new==NULL)
	{
		puts("入队失败!");
		return false;
	}
	//将数据存储在申请的空间
	new->data=data;
	
	//将new指向的结点插入到链式队列中
	new->next=q->rear->next;
	q->rear->next=new;
	
	//让rear指针指向新的队尾结点
	q->rear=q->rear->next;

	return true;
}

5. Leave the team

The C language implementation is as follows:

bool out_linkqueue(link_pqueue q,datatype *D)
{
	linkqueue_pnode t;
	//判断队列是否空
	if(is_empty_linkqueue(q)){
		printf("队列已空!\n");
		return false;
	}

	//出队
	t=q->front;
	q->front =q->front->next;
	*D=q->front->data;
	free(t);

	return true;
}

6. Print queue

The C language implementation is as follows:

void show_linkqueue(link_pqueue q)
{
	linkqueue_pnode p;
	if(is_empty_linkqueue(q))
		return;
	//非空时,从对头打印到队尾
	for(p=q->front->next;p!=NULL;p=p->next)
	{
		printf("%d\t",p->data);
	}
	printf("\n");
}

7. Queue linked list implementation source code

linkqueue.h

#ifndef __LINKQUEUE_H__
#define __LINKQUEUE_H__

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>

typedef int datatype;

typedef struct linkqueuenode{
	datatype data;
	struct linkqueuenode *next;
}linkqueue_node,*linkqueue_pnode;

typedef struct linkqueue{
	linkqueue_pnode front,rear;
}link_queue,*link_pqueue;

extern void init_linkqueue(link_pqueue *Q);
extern bool is_empty_linkqueue(link_pqueue q);
extern bool in_linkqueue(datatype data,link_pqueue q);
extern bool out_linkqueue(link_pqueue q,datatype *D);
extern void show_linkqueue(link_pqueue q);

#endif

linkqueue.c      

#include "linkqueue.h"

void init_linkqueue(link_pqueue *Q)
{
	//申请front和rear的空间
	*Q=(link_pqueue)malloc(sizeof(link_queue));
	if((*Q)==NULL)
	{
		perror("malloc");
		exit(-1);
	}
	//申请头结点空间
	(*Q)->front=(linkqueue_pnode)malloc(sizeof(linkqueue_node));
	if((*Q)->front==NULL)
	{
		perror("malloc");
		exit(-1) ;
	}

	(*Q)->front->next=NULL;
	(*Q)->rear=(*Q)->front;

	return;
}

//入队
bool in_linkqueue(datatype data,link_pqueue q)
{
	linkqueue_pnode  new;

	//申请数据结点空间
	new=(linkqueue_pnode)malloc(sizeof(linkqueue_node));
	if(new==NULL)
	{
		puts("入队失败!");
		return false;
	}
	//将数据存储在申请的空间
	new->data=data;
	
	//将new指向的结点插入到链式队列中
	new->next=q->rear->next;
	q->rear->next=new;
	
	//让rear指针指向新的队尾结点
	q->rear=q->rear->next;

	return true;
}

bool is_empty_linkqueue(link_pqueue q)
{
	if(q->rear == q->front)
		return true;
	else
		return false;
}

//出队
bool out_linkqueue(link_pqueue q,datatype *D)
{
	linkqueue_pnode t;
	//判断队列是否空
	if(is_empty_linkqueue(q)){
		printf("队列已空!\n");
		return false;
	}

	//出队
	t=q->front;
	q->front =q->front->next;
	*D=q->front->data;
	free(t);

	return true;
}

void show_linkqueue(link_pqueue q)
{
	linkqueue_pnode p;
	if(is_empty_linkqueue(q))
		return;
	//非空时,从对头打印到队尾
	for(p=q->front->next;p!=NULL;p=p->next)
	{
		printf("%d\t",p->data);
	}
	printf("\n");
}

test.c

#include "linkqueue.h"
/* 用链式队列实现如下功能:
 * 用户从键盘输入整数,程序将其入对;
 * 用户从键盘输入字母,程序将队头元素出队;
 * 并在每一次出队和入队之后打印队列元素。
 */
int main(int argc, const char *argv[])
{
	link_pqueue q;
	datatype data,t,ret;
	
	init_linkqueue(&q);

	while(1)
	{
		printf("请输入一个整数或字符:");
		ret=scanf("%d",&data);
		
		//输入整数时,入对
		if(ret == 1)
		{
			if(in_linkqueue(data,q))
				show_linkqueue(q);
		}
		else
		{
			//输入为字符时
			if(out_linkqueue(q,&t))
			{
				printf("out:%d\n",t);
				show_linkqueue(q);
			}
			//清空输入缓冲区
			while(getchar()!='\n');
		}
	}
	return 0;
}

Makefile 

CC = gcc
CFLAGS = -o0 -g -Wall

SRC=linkqueue.c test.c
OBJS=test

$(OBJS):$(SRC)
	$(CC) $(CFLAGS) -o $@ $^

.PHONY:clean
clean:
	rm -rf $(OBJS) *.o
  • "-o0" means the optimization level is 0, that is, optimization is turned off. This will result in a larger executable file, but can be easily debugged.
  • "-g" means generating debugging information so that you can view the values ​​of variables, function call stacks and other information when debugging the program.
  • "-Wall" means to enable all warnings, and the compiler will display all possible warning messages to help developers find potential problems.

Compilation result test:

Guess you like

Origin blog.csdn.net/m0_74712453/article/details/135351817