链式队列(带头结点)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Wan_shibugong/article/details/80102196

链式队列(无头结点)
注意事项:带头结点的链式队列在出队列时,出最后一个元素的与出其它元素不同,出非最后一个元素,队尾指针不变,一直指向第一个元素,当出最后一个元素时,队尾指针改变指向队头(也就是指向头结点),认真看看这里(这个例子并没看到带头结点方便)

//编译环境 VS2008
Queue.h

#pragma once

#include <stdio.h>
#include <assert.h>
#include <malloc.h>

typedef int DataType;

typedef struct Node
{
    struct Node* _Pnext;
    DataType _data;
}Node,*pNode;

typedef struct Queue
{
     pNode _pHead;
     pNode _pTail;
}Queue;

//初始化
void InitQueue(Queue * q);

//队列尾插
void QueuePush(Queue *q,DataType data);

//队列头删
void QueuePop(Queue *q);

//创建一个结点
pNode BuyNode(DataType data);

//队列是否为空
int QueueEmpty(Queue q);

//队列的大小
int QueueSize(Queue *q);

//队头元素
DataType Queuefront(Queue *q);

//队尾元素
DataType Queueback(Queue *q);

//销毁的队列
void QueueDestroy(Queue *q);

////////////////////////////////////////////////////
//Queue.c

#define _CRT_SECURE_NO_WARNINGS 1

#include "Queue.h"


//初始化
void InitQueue(Queue* q)
{
    assert(q);
    q->_pHead = q->_pTail =  BuyNode(0);
}

//队尾进元素
void QueuePush(Queue* q,DataType data)
{
    assert(q);
    q->_pTail->_Pnext = BuyNode(data);    //这里很重要
    q->_pTail = q->_pTail->_Pnext;
}

//队列头删
void QueuePop(Queue *q)
{
    assert(q);
    if(q->_pTail == q->_pHead)
    {
        printf("队列元素为空,无元素可删!!!\n");
        return;
    }
    else
    {
        pNode pDel = q->_pHead->_Pnext; 
        q->_pHead->_Pnext = q->_pHead->_Pnext->_Pnext;   
        if(pDel == q->_pTail)      //**重要***如果要出的元素是尾元素,这里需要为指针指向头,其他不需要改变尾指针的指向
            q->_pTail = q->_pHead;
        free(pDel);     //pDel不需要再指向NULL;因为本来就是临时变量,调用完函数自动销毁
    }
}

//判断队列是否为空
int QueueEmpty(Queue q)    //这里可以传队列的地址,但是直接传队列已经足够
{                           //因为复制的临时变量也可以查看队列是否为空
    return NULL == q._pHead;
}

//队列的大小
int QueueSize(Queue *q)
{
    pNode pCur = q->_pHead->_Pnext;
    int count = 0;
    assert(q);
    while(pCur)
    {
        ++count;
        pCur = pCur->_Pnext;
    }
    return count;
}

//队头元素
DataType Queuefront(Queue *q)
{
    assert(q);
    if(NULL == q->_pHead->_Pnext)
    {
        printf("队列为空,无队头元素!!!\n");
        assert(0);
    }
    return q->_pHead->_Pnext->_data;
}

//队尾元素
DataType Queueback(Queue *q)
{
    assert(q);
    if(NULL == q->_pTail)
    {
        printf("队列为空无队尾元素!!!\n");
        assert(0);
    }
    return q->_pTail->_data;
}

//新建一个结点
pNode BuyNode(DataType data)
{
    pNode pCur = (pNode)malloc(sizeof(Node));
    if(NULL == pCur)
    {
        printf("结点申请失败!!!\n");
        assert(0);
    }
    pCur->_data = data;
    pCur->_Pnext = NULL;
    return pCur;
}

//销毁队列
void QueueDestroy(Queue *q)
{
    pNode pCur = q->_pHead;
    assert(q);
    while(pCur)
    {
        pCur = pCur->_Pnext;
        free(q->_pHead);
        q->_pHead = pCur;
    }
    q->_pTail = NULL;
}

///////////////////////////////////////////////////////
//test.c

#define _CRT_SECURE_NO_WARNINGS 1


//
#include "Queue.h"

void QueueTest();
int main()
{
    QueueTest();
    return 0;
}

void QueueTest()
{
    Queue s;
    InitQueue(&s);
    QueuePush(&s,1);         //给队列入四个元素
    QueuePush(&s,2);
    QueuePush(&s,3);
    QueuePush(&s,4);


    printf("队列元素的个数size = %d\n",QueueSize(&s));       //队列元素的个数
    printf("队列队头元素 = %d\n",Queuefront(&s));//队列队头元素
    printf("队列队尾元素 = %d\n",Queueback(&s));  //队列队尾元素

    QueuePop(&s);                 //队列出两个元素
    QueuePop(&s);
    QueuePop(&s);


    printf("队列元素的个数 = %d\n",QueueSize(&s));
    printf("队列队头元素 = %d\n",Queuefront(&s));
    printf("队列队尾元素 = %d\n",Queueback(&s));

    printf("如果x打印为1,则为空反之不为空  x=%d\n",QueueEmpty(s));    //判断队列是否为空,0不为空

    QueueDestroy(&s);
}

猜你喜欢

转载自blog.csdn.net/Wan_shibugong/article/details/80102196