队列_单向链表

利用单向链表设计一个队列,实现“先进先出”的功能

​ 队列的两端都允许操作,只不过要求数据只能从队列的一端插入,从队列的另一端删除,可以把队列理解为一根水管,水管有进水口和出水口。

​ 一般把允许数据插入的一端称为队尾(Tail或者Rear),一般把允许删除数据的一端称为队头队首(Head或者Front)。

  • 把允许数据插入的一端称为队尾(允许数据插入到队列的操作称为入队,英文enqueue)
  • 把允许删除数据的一端称为队头(允许数据从队列删除的操作称为出队,英文dequeue)

程序结构思路:

.将单向链表的首结点当作堆首,尾结点当作队尾,入队相当于尾插操作,出队相当于头删操作。

程序:

/********************************************************************************************
*   file name: Queue_LList.c
*   author   : liaojx2016@126.com
*   date     : 2024/04/26
*   function : Design a queue to achieve “first input first output”
*   note     : None
*
*   CopyRight (c)  2023-2024   liaojx2016@126.com   All Right Reseverd 
*
*********************************************************************************************/
#include<stdio.h>
#include<string.h>
#include<stdbool.h>
#include<stdlib.h>
typedef int  DataType_t;
typedef struct QueueLList
{
	DataType_t  		 data; //结点的数据域
	struct QueueLList	*next; //结点的指针域

}QueueLList_t;
/**********************************************************************************************
*   func name       : QueueLList_Create
*   function        : Create a empty stack link list
*   func parameter  : None
*   return resuolt  : Address of head node
*   author          : liaojx2016@126.com
*   date            : 2024/04/26
*   note            : None
*   modify history  : None
*   function section: v1.0
*
**********************************************************************************************/
//创建一个空链表,空链表应该有一个头结点,对链表进行初始化
QueueLList_t * QueueLList_Create(void)
{
	//1.创建一个头结点并对头结点申请内存
	QueueLList_t *Head = (QueueLList_t *)calloc(1,sizeof(QueueLList_t));
    //判断是否内存申请成功
	if (NULL == Head)   {
		perror("Calloc memory for Head is Failed");
		exit(-1);
	}
	//2.对头结点进行初始化,头结点是不存储有效内容的!!!
	Head->next = NULL;
	//3.把头结点的地址返回即可
	return Head;
}
/**********************************************************************************************
*   func name       : QueueLList_NewNode
*   function        : Create a new node and do initialization
*   func parameter  : 
*                       @data :address of head node 
*   return resuolt  : Address of a new node
*   author          : liaojx2016@126.com
*   date            : 2024/04/26
*   note            : None
*   modify history  : None
*   function section: v1.0
*
**********************************************************************************************/
//创建新的结点,并对新结点进行初始化(数据域 + 指针域)
QueueLList_t * QueueLList_NewNode(DataType_t data)
{
	//1.创建一个新结点并对新结点申请内存
	QueueLList_t *New = (QueueLList_t *)calloc(1,sizeof(QueueLList_t));
	if (NULL == New)    {
		perror("Calloc memory for NewNode is Failed");
		return NULL;
	}
	//2.对新结点的数据域和指针域进行初始化
	New->data = data;
	New->next = NULL;

	return New;
}
/**********************************************************************************************
*   func name       : Enqueue
*   function        : Enqueue a data
*   func parameter  : 
*                       @data :Enqueue data
*                       @Head :Address of head node
*   return resuolt  : Enqueue success result (true or false)
*   author          : liaojx2016@126.com
*   date            : 2024/04/26
*   note            : None
*   modify history  : None
*   function section: v1.0
*
**********************************************************************************************/
bool Enqueue(QueueLList_t *Head,DataType_t data)
{
    //1.创建新的结点,并对新结点进行初始化
	QueueLList_t *New = QueueLList_NewNode(data);
	if (NULL == New)
	{
		printf("can not insert new node\n");
		return false;
	}
    //printf("New->data=%d\n",New->data);
	//2.判断链表是否为空,如果为空,则直接插入即可
	if (NULL == Head->next)
	{
		Head->next = New;
		return true;
	}
    //3.如果链表为非空,则把新结点插入到链表的尾部
    QueueLList_t *p = Head->next;
    //遍历链表,p指针到达尾结点
    while(p->next != NULL) {
        p = p->next;
    }
    //将新结点插入尾节点之后
    p->next = New;
    return true;
}
/**********************************************************************************************
*   func name       : Dequeue
*   function        : Dequeue a data and output
*   func parameter  : 
*                       @Head :address of head node 
*   return resuolt  : Dequeue success result (true or false)
*   author          : liaojx2016@126.com
*   date            : 2024/04/26
*   note            : None
*   modify history  : None
*   function section: v1.0
*
**********************************************************************************************/
bool Dequeue(QueueLList_t *Head)
{
    //当链表为空,删除失败,返回false
    if (NULL == Head->next)
	{
		//printf("Stack linklist is empty\n");
		return false;
	}
    QueueLList_t *p = Head->next;   //备份首结点
    printf("the dequeue element is %d\n",Head->next->data);
    //首部删除一个结点
    Head->next = Head->next->next;   //头结点的next指针指向首结点的直接后继
    p->next = NULL;	//将原首结点的next指针指向NULL
    free(p);	//释放原首结点
    return true;
}

/**********************************************************************************************
*   func name       : QueueLList_Print
*   function        : Queue data print
*   func parameter  : 
*                       @Head :address of head node 
*   return resuolt  : Print success result (true or false)
*   author          : liaojx2016@126.com
*   date            : 2024/04/25
*   note            : None
*   modify history  : None
*   function section: v1.0
*
**********************************************************************************************/
//遍历
bool QueueLList_Print(QueueLList_t *Head)
{
    if (Head->next == NULL)   {
        printf("stack link list is empty\n");
        return false;
    }
	//对链表的头文件的地址进行备份
	QueueLList_t *Phead = Head;
	printf("the Stack linkedlist data is \n");
    //遍历结点,输出数据
	do
	{
		//把头的直接后继作为新的头结点
		Phead = Phead->next;
		//输出头结点的直接后继的数据域
		printf("%d ",Phead->data);
	}
	while( Phead->next );
    printf("\n");
    return true;
}

int main(int argc, char const *argv[])
{
	//定义一个头指针
	QueueLList_t *head = QueueLList_Create();
	//Enqueue 入队,Dequeue 出队并输出数据,QueueLList_Print 遍历以便测试打印
    Enqueue(head,3);
    Dequeue(head);
    QueueLList_Print(head);
    Enqueue(head,7);
    Enqueue(head,4);
    Enqueue(head,2);
    QueueLList_Print(head);
    Dequeue(head);
    QueueLList_Print(head);
    
	return 0;
}

测试输出结果

posted @ 2024-04-26 20:50  沉舟道人  阅读(12)  评论(0编辑  收藏  举报