[Data structure] Interface implementation of the queue (with attached solution and source code)

Queue interface implementation (with diagram and source code)



foreword

This article mainly introduces the implementation of interfaces such as adding, deleting, checking and modifying in the column , and the total source code is attached at the end !


1. Define the structure

Here we implement the queue with the structure of linked list! (Higher efficiency than arrays) The
insert image description here
difference here is that it is different from the singly linked list: two structures need to be defined ! One represents the chain structure queue, and the other is the structure of the queue.

The code is as follows (example):

typedef int QDataType;
typedef struct QueueNode
{
    
    
	struct QueueNode* next;
	QDataType data;
}QNode;
typedef struct Queue
{
    
    
	QNode* head;
	QNode* tail;
	int size;
}Queue;

2. Interface implementation (attached solution + source code)

insert image description here
There are a total of 8 interfaces here, and I will implement them one by one ( source code + diagram )


1. Initialize the queue

The initialization of the queue is the same as the initialization of the single-linked list. For details, please refer to the initialization of the single-linked list !

The code is as follows (example):

void QueueInit(Queue* pq)
{
    
    
	assert(pq);
	pq->head = pq->tail = NULL;
	pq->size = 0;
}

2. Destroy the queue

insert image description hereFinally, don't forget to set pq->head and pq->tail to NULL

The code is as follows (example):

void QueueDestroy(Queue* pq)
{
    
    
	assert(pq);
	QNode* cur = pq->head;
	while (cur)
	{
    
    
		QNode* del = cur;
		cur = cur->next;
		free(del);
	}

	pq->head = pq->tail = NULL;
}

3. Enter the queue at the end of the queue

Open up a newnode space with malloc first!
insert image description here


insert image description here

The code is as follows (example):

void QueuePush(Queue* pq, QDataType x)
{
    
    
	assert(pq);
	QNode* newnode = (QNode*)malloc(sizeof(QNode));
	if (newnode == NULL)
	{
    
    
		perror("malloc fail");
		exit(-1);
	}
	else
	{
    
    
		newnode->data = x;
		newnode->next = NULL;
	}
	if (pq->tail == NULL)
	{
    
    
		pq->head = pq->tail = newnode;
	}
	else
	{
    
    
		pq->tail->next = newnode;
		pq->tail = newnode;
	}
	pq->size++;
}

Since we need to constantly judge whether the linked list is empty, we should write a function to judge whether the queue is empty .


4. Determine whether the queue is empty

Returns non-zero result if empty, 0 if non-empty

The code is as follows (example):

bool QueueEmpty(Queue* pq)
{
    
    
	assert(pq);
	return pq->head == NULL && pq->tail == NULL;
}

5. Head out of the queue

Note: When deleting the head-to-column, be aware that the queue can be empty, so use assert to assert!
insert image description here
There are also two cases here: 1. The queue has only one node, and 2. The queue has more than two nodes.


insert image description here


insert image description here


6. Get the queue head element

Just return pq->head->data directly .

The code is as follows (example):

QDataType QueueFront(Queue* pq)
{
    
    
	assert(pq);
	assert(!QueueEmpty(pq));
	return pq->head->data;
}

7. Get the tail element of the queue

Just return pq->tail->data directly .

The code is as follows (example):

QDataType QueueBack(Queue* pq)
{
    
    
	assert(pq);
	assert(!QueueEmpty(pq));
	return pq->tail->data;
}

8. Get the number of valid elements in the queue

Just return pq->size directly

The code is as follows (example):

int QueueSize(Queue* pq)
{
    
    
	assert(pq);
	return pq->size;
}

What should we do if we don't define size in the structure?
insert image description here

The code is as follows (example):

int QueueSize(Queue* pq)
{
    
    
	assert(pq);
	QNode* cur = pq->head;
	int n = 0;
	while (cur)
	{
    
    
		++n;
		cur = cur->next;
	}
	return n;
}

3. Source code display

1.test.c (test + main function)

The code is as follows (example):

//#include <stdio.h>
//
//int f(int n)
//{
    
    
//	return n == 1 ? 1 : f(n - 1) + n;
//}
//
//int main()
//{
    
    
//	printf("%d\n", f(10000));
//	
//	return 0;
//}
#include <stdio.h>
#include "Stack.h"
#include "Queue.h"
// 解耦 -- 低耦合 高内聚
// 数据结构建议不要直接访问结构数据,一定要通过函数接口访问
void TestStack()
{
    
    
	ST st;
	StackInit(&st);
	StackPush(&st, 1);
	StackPush(&st, 2);
	StackPush(&st, 3);
	printf("%d ", StackTop(&st));
	StackPop(&st);
	printf("%d ", StackTop(&st));
	StackPop(&st);
	StackPush(&st, 4);
	StackPush(&st, 5);
	while (!StackEmpty(&st))
	{
    
    
		printf("%d ", StackTop(&st));
		StackPop(&st);
	}
	printf("\n");
}
void TestQueue()
{
    
    
	Queue q;
	QueueInit(&q);
	QueuePush(&q, 1);
	QueuePush(&q, 2);
	QueuePush(&q, 3);
	printf("%d ", QueueFront(&q));
	QueuePop(&q);
	printf("%d ", QueueFront(&q));
	QueuePop(&q);
	QueuePush(&q, 4);
	QueuePush(&q, 4);
	QueuePush(&q, 4);
	while (!QueueEmpty(&q))
	{
    
    
		printf("%d ", QueueFront(&q));
		QueuePop(&q);
	}
	printf("\n");
	QueueDestroy(&q);
}
int main()
{
    
    
	//TestStack();
	TestQueue();
	return 0;
}

2.Queue.h (declaration of interface function)

The code is as follows (example):

#pragma once
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <stdbool.h>
typedef int QDataType;
typedef struct QueueNode
{
    
    
	struct QueueNode* next;
	QDataType data;
}QNode;
typedef struct Queue
{
    
    
	QNode* head;
	QNode* tail;
	int size;
}Queue;

void QueueInit(Queue* pq);//初始化队列
void QueueDestroy(Queue* pq);//销毁队列
void QueuePush(Queue* pq, QDataType x);//队尾入队列
void QueuePop(Queue* pq);//队头入队列
QDataType QueueFront(Queue* pq);//获取队列头部元素
QDataType QueueBack(Queue* pq);//获取队列尾部元素
bool QueueEmpty(Queue* pq);//判断队列是否为空
int QueueSize(Queue* pq);//获取队列中有效元素个数

3.Queue.c (implementation of interface functions)

The code is as follows (example):

#include "Queue.h"
void QueueInit(Queue* pq)
{
    
    
	assert(pq);
	pq->head = pq->tail = NULL;
	pq->size = 0;
}
void QueueDestroy(Queue* pq)
{
    
    
	assert(pq);
	QNode* cur = pq->head;
	while (cur)
	{
    
    
		QNode* del = cur;
		cur = cur->next;
		free(del);
	}
	pq->head = pq->tail = NULL;
}
void QueuePush(Queue* pq, QDataType x)
{
    
    
	assert(pq);
	QNode* newnode = (QNode*)malloc(sizeof(QNode));
	if (newnode == NULL)
	{
    
    
		perror("malloc fail");
		exit(-1);
	}
	else
	{
    
    
		newnode->data = x;
		newnode->next = NULL;
	}
	if (pq->tail == NULL)
	{
    
    
		pq->head = pq->tail = newnode;
	}
	else
	{
    
    
		pq->tail->next = newnode;
		pq->tail = newnode;
	}
	pq->size++;
}
void QueuePop(Queue* pq)
{
    
    
	assert(pq);
	assert(!QueueEmpty(pq));

	if (pq->head->next == NULL)
	{
    
    
		free(pq->head);
		pq->head = pq->tail = NULL;
	}
	else
	{
    
    
		QNode* del = pq->head;
		pq->head = pq->head->next;

		free(del);
		del = NULL;
	}

	pq->size--;
}
QDataType QueueFront(Queue* pq)
{
    
    
	assert(pq);
	assert(!QueueEmpty(pq));
	return pq->head->data;
}
QDataType QueueBack(Queue* pq)
{
    
    
	assert(pq);
	assert(!QueueEmpty(pq));
	return pq->tail->data;
}
bool QueueEmpty(Queue* pq)
{
    
    
	assert(pq);
	return pq->head == NULL && pq->tail == NULL;
}
int QueueSize(Queue* pq)
{
    
    
	assert(pq);
	/*QNode* cur = pq->head;
	int n = 0;
	while (cur)
	{
		++n;
		cur = cur->next;
	}
	return n;*/
	return pq->size;
}

Summarize

The above is what I want to talk about today. This article introduces the diagram + source code of the simulation implementation of the 8 interfaces of the queue.
If my blog is helpful to you, remember to support it three times. Thank you for your support!
insert image description here

Guess you like

Origin blog.csdn.net/2201_75587702/article/details/129248552