【考研数据结构】带头结点和不带头结点的链式队列及其基本操作的C语言实现

带头结点的链式队列

  1. 队首指针front指向头节点,所以队头元素是front->next
  2. 队尾指针rear就指向队尾节点
  3. 判空条件:Q.front==Q.rear,即头尾指针指向同一个位置
#include<stdio.h>
#include<stdbool.h>
#include<stdlib.h>


//队列中的节点
typedef struct LinkNode
{
    int data;
    struct LinkNode *next;
}LinkNode;


//队列,头节点一端是队头,另一端是队尾
typedef struct{
    LinkNode *front,*rear;
}LinkQueue;

//带头结点的初始化
void InitQueue(LinkQueue *Q){
    //初始化时,front和rear都指向头节点
    (*Q).front = (*Q).rear = (LinkNode*)malloc(sizeof(LinkNode));
    //头节点的next指向空
    (*Q).front->next=NULL;
}

//判断队列是否为空
bool IsEmpty(LinkQueue q){
    if(q.front==q.rear)
    {
        printf("Queue is Empty !\n");
        return true;
    }

    else{
        printf("Queue is Not Empty!\n");
        return false;
    }
}

//顺序输出队列中的所有元素
bool ReadQueue(LinkQueue Q){
    LinkNode *p;
    p=Q.front->next;//p指向队首元素
    if(IsEmpty(Q))
    { 
        return false;
    }
    
    while(p!=NULL)
    {
        printf("The value we are reading is %d\n",p->data);
        p=p->next;
    }
    return true;
}


//带有头结点的入队操作
bool EnQueue(LinkQueue *Q,int x){
    LinkNode *s=(LinkNode*) malloc (sizeof(LinkNode));
    s->data=x;
    s->next=NULL;
    (*Q).rear->next=s;//把新节点放到队尾的位置
    (*Q).rear=s;//移动尾指针,指向新节点
    return true;
}


//带有头节点的出队操作,就是删除链表的1号节点
bool DeQueue(LinkQueue *Q, int *x){

    if( (*Q).front == (*Q).rear ){
        printf("Error:Queue is empty, DeQueue failed !\n");
        return false;
    }

    LinkNode *p;
    p=(*Q).front->next;//p指针指向我们要删除的节点
    (*x)=p->data;
    (*Q).front->next=p->next;//移动队头指针到新的队首,front永远指向头节点,所以这里队首元素是front->next!!!
    
    /*删除的元素是最后一个元素时,我们要把尾指针移回到头节点*/
    if( (*Q).rear == p )
    {
        (*Q).rear=(*Q).front;
    }

    free(p);//释放节点
    return true;    
}

不带头结点的链式队列

  1. 队首指针front指向队首元素
  2. 队尾指针rear指向队尾元素
  3. 判空条件为front==NULL
//不带头节点的队列的初始化
/*因为没有头节点,所以初始化时,rear和front都指向NULL*/
void InitalQueue(LinkQueue *Q)
{
    (*Q).rear=(*Q).front=NULL;
}

//判断不带头结点的队列是否为空,由于没有头节点,所以判空条件就是front指针是否指向空(队头都没有数据,队尾更不可能有了)
bool isEmpty(LinkQueue Q){
    if(Q.front==NULL)
    {
        printf("Queue is Empty\n");
        return true;
    }

    else{
        printf("Queue is Not Empty\n");
        return false;
    }
}

//带头结点的队列入队,入队第一个元素时要单独处理
bool Enqueue(LinkQueue* Q, int x){
    //s是新入队的元素
    LinkNode *s=(LinkNode*)malloc(sizeof(LinkNode));
    s->data=x;
    s->next=NULL; //队尾元素指向空

    if( (*Q).front==NULL )//此时插入第一个元素,要单独处理
    {
        (*Q).front=s;
        (*Q).rear=s;
        return true;
    }

    (*Q).rear->next=s;//队尾元素入队
    (*Q).rear=s;//移动队尾指针指向队尾元素
    return true;
}

//带头节点的元素出队
bool Dequeue(LinkQueue* Q,int *x){
    if( (*Q).front==NULL )
    {
        printf("ERROR: Queue is Empty, failed to Dequeue\n");
        return false;
    }

    LinkNode *p= (*Q).front;  //创建一个指针,指向队头元素
    *x=p->data;  //出队元素的值
    (*Q).front=p->next;//移动队头指针

    if( (*Q).rear == p )//此时出队元素是最后一个元素
    {
        (*Q).front==NULL;
        (*Q).front==NULL;
    } 
    free(p);
    return true;

}

//读取不带头结点的队列中的所有数据元素
bool readQueue(LinkQueue Q){
    if(Q.front==NULL)
    {  
        printf("Queue is empty,failed to read it!\n ");
        return false;
    }

    LinkNode *p;
    p=Q.front;

    while(p!=NULL){
        printf("The value of the Node we are reading is %d \n",p->data);
        p=p->next;

    }
    return true;
}
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值