刁肥宅手笔:纯C语言实现链式队列的相关操作

       先上图,以图服人:

图一 程序运行截图1
图二 程序运行截图2

       上代码:

       头文件LinkQueue.h:

/*LinkQueue.h*/

#ifndef LINKQUEUE_H_INCLUDED
#define LINKQUEUE_H_INCLUDED
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#include <stdbool.h>
#include <time.h>
#include <windows.h>

typedef int LQElementType;
typedef struct Node
{
    LQElementType Data;
    struct Node *Next;
}LNode,*PNode;

typedef struct LinkQueue
{
    LNode *Front,*Rear;

}LQueue,*PQueue;

PQueue InitiateQueue(PQueue LQ);/*初始化队列*/
void DestroyQueue(PQueue LQ);/*销毁队列*/
void Display(PQueue LQ);/*打印队列:边出队边打印队首元素,不推荐使用*/
void ShowQueue(PQueue LQ);/*打印队列2*/
bool ClearQueue(PQueue LQ);/*清空队列*/
bool EmptyQueue(PQueue LQ);/*判断队列是否为空*/
bool EnQueue(PQueue LQ,LQElementType Value);/*队尾入队*/
bool DeQueue(PQueue LQ,LQElementType *Tmp);/*队首出队*/
bool GetFront(PQueue LQ,LQElementType *Tmp);/*获取队首元素*/
int QueueSize(PQueue LQ);/*返回队列长度*/


#endif // LINKQUEUE_H_INCLUDED

       源文件test.c:

/*test.c*/

/*
	Name:纯C语言实现链式队列的相关操作
	Copyright:2018
	Author:刁肥宅
	Date: 06/08/18 17:49
	Description:一切尽在注释中!
*/

#include "LinkQueue.h"

int main()
{
	srand(time(NULL));
    LQueue *LQ = (LQueue *)malloc(sizeof(LQueue)),*LQ2 = NULL;
    int Value,i,QueueLength,Line = 0,FirstKey = -1;
    int DeQueueFrequency = 0,EnQueueFrequency = 0,ChoosingKey,RandomEnQueueValue = 0,RandomOperatingSize = 0;
	LQ = InitiateQueue(LQ);
	LQ2 = LQ;
	QueueLength = rand() % 1000 + 1;

	for(i = 0;i < QueueLength;i ++)
	{
		Value = rand() % 10000 + 1;
		/*Value = 100;*/
		if(EnQueue(LQ,Value))
			continue;
		else
			break;
	}

	for(i = 0;i < RandomOperatingSize;i ++)
    {
        ChoosingKey = rand() % 2 + 0;
        if(!ChoosingKey)
        {
            if(DeQueue(LQ2,&FirstKey))
                DeQueueFrequency ++;
            /*else
                continue;*/
        }
        else
        {
            RandomEnQueueValue = rand() % 10000 + 1;
            if(EnQueue(LQ2,RandomEnQueueValue))
                EnQueueFrequency ++;
        }
    }

	int n = QueueSize(LQ);
	printf("QueueSize() = %d\n",n);

	ShowQueue(LQ);
	printf("\n\n");
	/*Display(LTmp);*/

	DeQueue(LQ,&FirstKey);
	printf("FirstKey = %d\n",FirstKey);

	if(GetFront(LQ,&FirstKey))
		printf("After DeQueue,FirstKey = %d\n\n",FirstKey);
	else
		printf("GetFront Error.\n");


    printf("EnQueueFrequency = %d,DeQueueFrequency = %d\n",EnQueueFrequency,DeQueueFrequency);

	ClearQueue(LQ);
	int n2 = QueueSize(LQ);
	printf("QueueSize() = %d\n",n2);
	DestroyQueue(LQ);
	int n1 = QueueSize(LQ);
	printf("QueueSize() = %d\n",n1);

	if(LQ->Front->Next == NULL)
		printf("DestroyQueue Succeed\n");
	else
	{
		if(EmptyQueue(LQ))
			printf("Empty\n");
		else
			printf("Not Empty\n");
	}
    /*
	LQ2 = InitiateQueue(LQ2);
	RandomOperatingSize = rand() % 1000 + 1;

	for(i = 0;i < RandomOperatingSize;i ++)
	{
		Value = rand() % 1000 + 1;

		if(EnQueue(LQ2,Value))
			continue;
		else
			break;
	}

    for(i = 0;i < RandomOperatingSize;i ++)
    {
        ChoosingKey = rand() % 2 + 0;
        if(!ChoosingKey)
        {
            if(DeQueue(LQ,&FirstKey))
                DeQueueFrequency ++;
            else
                continue;
        }
        else
        {
            RandomEnQueueValue = rand() % 10000 + 1;
            if(EnQueue(LQ,RandomEnQueueValue))
                EnQueueFrequency ++;
        }
    }
    n2 = QueueSize(LQ2);
	printf("QueueSize() = %d\n",n2);
	if(GetFront(LQ2,&FirstKey))
		printf("Key = %d\n\n",FirstKey);
	else
		printf("GetFront Error.\n");
    ShowQueue(LQ2);
    printf("EnQueueFrequency = %d,DeQueueFrequency = %d\n",EnQueueFrequency,DeQueueFrequency);
    */
	printf("\n");
    printf("The screen will be closed in 60 seconds.\n");
    Sleep(1000 * 60);
    return 0;
}

PQueue InitiateQueue(PQueue LQ)
{
    LQ->Front = LQ->Rear = (LNode *)malloc(sizeof(LNode));
    /*LQ->Front = LQ->Rear;*/
    if(!LQ->Front)
    {
        printf("Initiate failed.\n");
        exit(EXIT_FAILURE);
    }
    LQ->Front->Next = NULL;
    return LQ;
}

bool EmptyQueue(PQueue LQ)
{
    return LQ->Front == LQ->Rear;
}

bool EnQueue(PQueue LQ,LQElementType Value)
{
    LNode *QueueNodeTmp = (LNode *)malloc(sizeof(LNode));
    QueueNodeTmp->Next = NULL;
	QueueNodeTmp->Data = Value;
    /*if(QueueEmpty(LQ))*/
	if(!LQ->Rear)
        LQ->Front = LQ->Rear = QueueNodeTmp;
    else
    {
        LQ->Rear->Next = QueueNodeTmp;
        LQ->Rear = QueueNodeTmp;
    }
	return true;
}

bool DeQueue(PQueue LQ,LQElementType *Tmp)
{
    if(!LQ->Front)
        return false;
    /*
	LNode *NodeTmp = (LNode *)malloc(sizeof(LNode));
    NodeTmp = LQ->Front;

	*Tmp = LQ->Front->Next->Data;*/
	LNode *NodeTmp = LQ->Front;
	*Tmp = NodeTmp->Next->Data;
	/*
	上面这句话我原来写作:
	*Tmp = LQ->Front->Data;
	等价于:
	*Tmp = NodeTmp->Data;
	导致 Display 函数 调用 DeQueue 函数时,第一个打印出来的总是随机数值。
	原因:
	第一次加载数据没有走EnQueue 函数的 if 条件语句,然后 LQ->Front->Data 就没值(不指向Next无
	法识别数据域)
	症结:不理解指针、队列的某些基本概念
	*/
    LQ->Front = NodeTmp->Next;
	if(NodeTmp == LQ->Rear)
		LQ->Front = LQ->Rear;
    free(NodeTmp);
    if(!LQ->Front)
        LQ->Rear = NULL;
	/*NodeTmp = NULL;*/
    return true;
}

void DestroyQueue(PQueue LQ)
{
    LNode *Tmp = (LNode *)malloc(sizeof(LNode));

	/*solution 1:*/
    while(LQ->Front != LQ->Rear)
    {
        Tmp = LQ->Front->Next;

        free(LQ->Front);
		LQ->Front = Tmp;
    }

	/*solution 2(badly function):
	while(LQ->Front != NULL)
	{
		Tmp = LQ->Front;
		LQ->Front = Tmp->Next;
		free(Tmp);
	}
	*/
	LQ->Front->Next = LQ->Rear->Next = NULL;
	/*LQ->Front = LQ->Rear;*/
}

bool ClearQueue(PQueue LQ)
{
	if(EmptyQueue(LQ))
		return false;
	LQ->Front = LQ->Rear;
	return true;
}

void Display(PQueue LQ)
{
	int x = -1,Line = 0;
	if(LQ->Front == LQ->Rear)
	{
		printf("Empty Queue.\n");
		exit(EXIT_FAILURE);
	}
	while(LQ->Front != LQ->Rear)
	{
		/*printf("%-6d",LQ->Front->Data);
		LQ = LQ->Front;*/
		if(DeQueue(LQ,&x))
		{
			printf("%-6d",x);
			++ Line;
			if(Line % 10 ==0)
				printf("\n");
		}
	}
}

void ShowQueue(PQueue LQ)
{
	/*
	LNode *Tmp = (LNode *)malloc(sizeof(LNode));
	Tmp	= LQ->Front->Next;
	*/
	LNode *Tmp = LQ->Front->Next;
	int Line = 0;
	while(Tmp)
	{
		printf("%-6d",Tmp->Data);
		++ Line;
		if(Line % 10 == 0)
			printf("\n");
		Tmp = Tmp->Next;
	}
}

bool GetFront(PQueue LQ,LQElementType *Tmp)
{
    if(!LQ->Front)
        return false;
    *Tmp = LQ->Front->Next->Data;
	return true;
}

int QueueSize(PQueue LQ)
{
	if(!LQ->Front)
		return -1;
    LNode *Tmp = LQ->Front;
    int ID = 0;
    while(LQ->Rear != Tmp)
    {
        Tmp = Tmp->Next;
        ++ ID;
    }
    return ID;
}

猜你喜欢

转载自blog.csdn.net/u25th_engineer/article/details/81458380