数据结构--8链队

链队

(相当于开创一个结构体,结构体里跟随一个链表)

结构体声明和宏

typedef int data_t;
//构造链表节点类型
typedef struct node{
    data_t data;
    struct node *next;//指针域
}linklist;
//构造链式队列类型   //相当与构建头节点、尾节点
typedef struct{
    linklist *front;//保存队头节点的前一个节点的地址
    linklist *rear;//保存队尾节点的地址
}lqueue;

注意的两个结构体里的类型和相互的关系

1.创建空链队(类似于创建头节点)

//创建空链式队列
lqueue *createLqueue()
{
    lqueue *lq = (lqueue *)malloc(sizeof(lqueue));//给链式队列开空间
        if(NULL == lq)    return NULL;
        
    lq->front = (linklist *)malloc(sizeof(linklist));//给链表头节点开空间
     if(lq->front == NULL)     return NULL;

     lq->rear = lq->front;        //空

    lq->front->data = -1;
    lq->front->next = NULL;

    return lq;
}

注意创建的节点的关系,以及初始化为空,故front=rear

2.判空

//判空
int lqueue_is_empty(lqueue *lq)
{
    if(NULL == lq)
        return -1;
    else
        return ((lq->front == lq->rear)?1:0);        
}

3.求节点个数

int getLengthLqueue(lqueue *lq)
{
    if(lq == NULL)
     return -1;
    int num = 0;
    linklist *p = lq->front->next;
    while(p != NULL)
    {
    num++;
    p = p->next;
    }
    return num;
}

4.入队

//入队,在队尾入队
int enLqueue(lqueue *lq,data_t data)
{
    if(NULL == lq)            return -1;
linklist *new = (linklist *)malloc(sizeof(linklist));//准备新节点
    if(NULL == new)        return -1;

    new->data = data;
    new->next = NULL;
                //rear本来就记录着尾节点,不用遍历到尾部
            //将new节点插入到队尾
lq->rear->next = new;    
lq->rear = new;//new节点为队尾节点,更新尾部
        
    return 0;
}

注意尾部的更新

5.出队(两种方式)

//出队
//head保持不变,删除第一个节点,需要判断是否为空
data_t deLqueue(lqueue *lq)
{
     if(lq == NULL)    return -1;        
     if(lqueue_is_empty(lq))    return -1;
        
  
    linklist *q = lq->front->next;    //q指针保存队头节点(第一个节点)的地址    、head保持不变
    data_t data = q->data;            //data变量保存队头元素的data值    
    lq->front->next = q->next;        //删除队头节点(第一个节点)
 
    if(lq->front->next == NULL)        //判断队列是否为空
        lq->rear = lq->front;        //front和rear指针指向头节点

    free(q);
    q = NULL;

    return data;
}
//head向后移动,不断删除头节点,再重新赋头节点,不用判断,head(lq->front)和lq->rear相遇时就为空了
data_t deLqueue(lqueue *lq)
{
     if(lq == NULL)    return -1;        
     if(lqueue_is_empty(lq))    return -1;
     
     data_t tmp=lq->front->next->data;        //运用的是删除head头节点的方式
     linklist *q=lq->front;                    // 将lq->front给下一个节点,该节点被当作头节点数据区无效了,效果相同
     lq->front=lq->front->next;
     free(q);             //不用判断是否为空,删除头节点,front所在就是头节点,为空时回合rear相遇
 }

注意判断最后一个节点删除后,应该front=rear
在这里插入图片描述

6.show

//打印队列中各个节点的daya值
void printLqueue(lqueue *lq)
{
    if(NULL == lq)    return;        
    if(lqueue_is_empty(lq))    return;
         
linklist *p = lq->front->next;//p变量保存的是队头节点的地址
    while(p != NULL)//遍历队列
    {
        printf("%d ",p->data);
    p = p->next;
    }
    printf("\n");
    return;
}

重新让一个节点p指向头,让其用来遍历,就不用一直释放遍历

算法思路

在这里插入图片描述
创建倒数第二行代码:lq->front->next=NULL
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

数据结构参考网站:
https://visualgo.net/en/list

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值