C语言--栈与队列4(链队)

一、链队的基本操作(明确链队的头指针所指向的结点不使用)

0)链队的定义和一些宏定义

#define MaxSize 100
#define ElementType char//如果要修改数据类型,只需修改这里的宏定义,入队出队的打印,取对头元素,主函数scanf和printf
#define LEN sizeof(QueueNode)
//链队的一个结点
typedef struct QueueNode{
    ElementType Data;
    struct QueueNode*Next;
}QueueNode,*QueuePointer;
//链队的头指针尾指针,链队的头指针指向的结点数据域为空,也就是少用这个元素的空间
typedef struct{
    QueuePointer Head;
    QueuePointer Back;
}LinkQueue;

1)链队的初始化---先开辟一个结点,并且在第一次入队操作中不会对第一个结点进行数据域赋值

//初始化
void Init_LinkQueue(LinkQueue* queue){
    queue->Head=queue->Back=(QueuePointer)malloc(LEN);
    if(queue->Head==NULL){
        printf("初始化链队失败!\n");
        exit(0);
    }
    else{
        (queue->Head)->Next=NULL;//头指针指向的结点的Next指向空
        printf("初始化链队成功!\n");
    }
}

2)销毁---包括第一个结点

//销毁,第一个结点也会被释放
void Destroy_LinkQueue(LinkQueue* queue){
    QueuePointer Temp;
    while(queue->Head!=NULL){
        Temp=(queue->Head)->Next;
        free(queue->Head);
        queue->Head=Temp;
    }
    if(queue->Head==NULL)   printf("\n链队销毁成功!\n");
}

3)入队---明确第一次入队不会对初始化产生的第一个结点进行数据域赋值

//入队,队尾插入,初始化后第一次的入队并不会给第一个结点赋值数据域,而是开辟第二个结点并给其数据域赋值
void Enter_LinkQueue(LinkQueue* queue,ElementType data){
    QueuePointer Temp;
    Temp=(QueuePointer)malloc(LEN);
    if(Temp==NULL){
        printf("开辟空间出错,入队失败!\n");
    }
    else{
        Temp->Data=data;//数据域
        Temp->Next=NULL;//指针域
        (queue->Back)->Next=Temp;//连接
        (queue->Back)=Temp;//更新
        printf("%c元素入队成功!\n",(queue->Back)->Data);
    }
}

4)出队---时时刻刻判断是否对空(对空标志是只剩下第一个结点)

//出队队头删除,时时刻刻判断是否为空,少用了一个结点的空间即头指针指向的结点
void Out_LinkQueue(LinkQueue* queue,ElementType* data){
    QueuePointer Temp;
    //如果链队为空
    if((queue->Head)->Next==NULL){
        queue->Back=queue->Head;
        (queue->Back)->Next=NULL;
        printf("链队为空,无法出队!\n");
    }
    else{
        Temp=(queue->Head)->Next;
        (queue->Head)->Next=Temp->Next;
        *data=Temp->Data;
        free(Temp);
        printf("%c元素出队成功!\n",*data);
    }
}

5)计算链队结点个数---包括头结点

//计算链队长度,包括头结点
int LinkQueue_Length(LinkQueue queue){
    QueuePointer Temp;
    int length=0;
    Temp=queue.Head;
    while(Temp!=NULL){
        length++;
        Temp=Temp->Next;
    }
    return length;
}

6)取队头元素---头指针所指的结点的下一个位置

//取队头元素,在头指针所指的结点的下一个位置
void Get_LinkQueue_Head(LinkQueue queue,ElementType* data){
    if((queue.Head)->Next==NULL){
        printf("链队已空,无法取出队头元素!\n");
    }
    else{
        *data=(queue.Head)->Next->Data;
    } 
}

二、实践

链队初始化

3次入队并计算长度

4次出队并计算长度

再次3次入队并计算长度

取队头元素显示

销毁并计算长度

#include <stdio.h>
#include <stdlib.h>
#define MaxSize 100
#define ElementType char//如果要修改数据类型,只需修改这里的宏定义,入队出队的打印,取对头元素,主函数scanf和printf
#define LEN sizeof(QueueNode)
//链队的一个结点
typedef struct QueueNode{
    ElementType Data;
    struct QueueNode*Next;
}QueueNode,*QueuePointer;
//链队的头指针尾指针,链队的头指针指向的结点数据域为空,也就是少用这个元素的空间
typedef struct{
    QueuePointer Head;
    QueuePointer Back;
}LinkQueue;
//初始化
void Init_LinkQueue(LinkQueue* queue){
    queue->Head=queue->Back=(QueuePointer)malloc(LEN);
    if(queue->Head==NULL){
        printf("初始化链队失败!\n");
        exit(0);
    }
    else{
        (queue->Head)->Next=NULL;//头指针指向的结点的Next指向空
        printf("初始化链队成功!\n");
    }
}
//销毁,第一个结点也会被释放
void Destroy_LinkQueue(LinkQueue* queue){
    QueuePointer Temp;
    while(queue->Head!=NULL){
        Temp=(queue->Head)->Next;
        free(queue->Head);
        queue->Head=Temp;
    }
    if(queue->Head==NULL)   printf("\n链队销毁成功!\n");
}
//入队,队尾插入,初始化后第一次的入队并不会给第一个结点赋值数据域,而是开辟第二个结点并给其数据域赋值
void Enter_LinkQueue(LinkQueue* queue,ElementType data){
    QueuePointer Temp;
    Temp=(QueuePointer)malloc(LEN);
    if(Temp==NULL){
        printf("开辟空间出错,入队失败!\n");
    }
    else{
        Temp->Data=data;//数据域
        Temp->Next=NULL;//指针域
        (queue->Back)->Next=Temp;//连接
        (queue->Back)=Temp;//更新
        printf("%c元素入队成功!\n",(queue->Back)->Data);///
    }
}
//出队队头删除,时时刻刻判断是否为空,少用了一个结点的空间即头指针指向的结点
void Out_LinkQueue(LinkQueue* queue,ElementType* data){
    QueuePointer Temp;
    //如果链队为空
    if((queue->Head)->Next==NULL){
        queue->Back=queue->Head;
        (queue->Back)->Next=NULL;
        printf("链队为空,无法出队!\n");
    }
    else{
        Temp=(queue->Head)->Next;
        (queue->Head)->Next=Temp->Next;
        *data=Temp->Data;
        free(Temp);
        printf("%c元素出队成功!\n",*data);///
    }
}
//计算链队长度,包括头结点
int LinkQueue_Length(LinkQueue queue){
    QueuePointer Temp;
    int length=0;
    Temp=queue.Head;
    while(Temp!=NULL){
        length++;
        Temp=Temp->Next;
    }
    return length;
}
//取队头元素,在头指针所指的结点的下一个位置
void Get_LinkQueue_Head(LinkQueue queue,ElementType* data){
    if((queue.Head)->Next==NULL){
        printf("链队已空,无法取出队头元素!\n");
    }
    else{
        *data=(queue.Head)->Next->Data;
    } 
}
int main(){
    LinkQueue queue;
    char data;
    printf("提示:链队的第一个结点规定不用,但是链队结点个数有包括第一个结点!\n\n");
    //初始化
    Init_LinkQueue(&queue);
    printf("\n");
    //3次入队
    Enter_LinkQueue(&queue,'a');
    Enter_LinkQueue(&queue,'b');
    Enter_LinkQueue(&queue,'c');
    //计算长度
    printf("\n包括第一个结点,链队结点有%d个\n",LinkQueue_Length(queue));
    printf("\n");
    //4次出队
    Out_LinkQueue(&queue,&data);
    Out_LinkQueue(&queue,&data);
    Out_LinkQueue(&queue,&data);
    Out_LinkQueue(&queue,&data);
    //计算长度
    printf("\n包括第一个结点,链队结点有%d个\n",LinkQueue_Length(queue)); 
    printf("\n");  
    //再次入队
    Enter_LinkQueue(&queue,'A');
    Enter_LinkQueue(&queue,'B');
    Enter_LinkQueue(&queue,'C');
    //计算长度
    printf("\n包括第一个结点,链队结点有%d个\n",LinkQueue_Length(queue)); 
    //取队头元素
    Get_LinkQueue_Head(queue,&data);
    printf("\n");
    printf("队头元素是%c\n",data);
    //销毁
    Destroy_LinkQueue(&queue);
    //计算长度
    printf("\n包括第一个结点,链队结点有%d个\n",LinkQueue_Length(queue));   
    return 0; 
}

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值