链式队列用下标(下标从1开始)进行元素的删除与插入操作

#include "stdio.h"
#include "stdlib.h"


typedef int ElemType;
 
//值节点--多个 
typedef struct Node
{
    ElemType data;//存储队列的元素值 
    struct Node *next;//存储下一个元素节点的地址 
}DataNode;

//头节点--1个 
typedef struct
{
    DataNode* front;//存储队头元素节点的地址 (队首指针) 
    DataNode* rear;//存储队尾元素节点的地址 (队尾指针)
}LinkQueue;

//链表初始化
LinkQueue * InitQueue(LinkQueue* Q);
//出队操作
int deQueue(LinkQueue *Q,ElemType *e);
//销毁队列,删除所有链队节点和数据节点
void DestroyQueue(LinkQueue *Q);
//判断队列为空
int QueueEmpty(LinkQueue *Q);
//录入数据
void EnQueue(LinkQueue *Q,ElemType e);
//求队列长度
int lenghtLinkQueue(LinkQueue *Q);
//打印队列中的元素
void DispQueue(LinkQueue *Q);
//根据下标插入元素操作,下标从1开始
int Insertdata(LinkQueue* Q,int count,ElemType e);
//根据下标删除元素操作,下标从1开始
int Deletedata(LinkQueue* Q,int count);

int main(){
    int count = 0;
    ElemType e;
    LinkQueue *Q = NULL;
    Q = InitQueue(Q);
    printf("输入数据(0:结束):\n");
    scanf("%d",&e);
    while(e!=0){
        EnQueue(Q,e);
        scanf("%d",&e);
    }
    DispQueue(Q);
    printf("插入元素操作:\n");
    printf("请输入插入元素的位置:");
    scanf("%d",&count);
    while(count<1||count > lenghtLinkQueue(Q)+1){
        printf("输入位置超过队列的长度,当前队列的长度为%d\n,请重新输入:",lenghtLinkQueue(Q));
        scanf("%d",&count);
    }
    printf("请输入插入的数据的数据值:");
    scanf("%d",&e);
    if(!Insertdata(Q,count,e))  printf("插入失败。\n");    
    DispQueue(Q);
    printf("删除元素操作:\n");
    printf("请输入删除元素的位置:");
    scanf("%d",&count);    
    while(count<1||count > lenghtLinkQueue(Q)){
        printf("输入位置超过队列的长度,当前队列的长度为%d\n,请重新输入:",lenghtLinkQueue(Q));
        scanf("%d",&count);
    }    
    Deletedata(Q,count);
    DispQueue(Q);
    
    DestroyQueue(Q);
}

//链表初始化
LinkQueue* InitQueue(LinkQueue* Q)
{
    Q=(LinkQueue *)malloc(sizeof(LinkQueue));
    Q->front=NULL;
    Q->rear=NULL;
    return Q;


//出队操作
/* 
若队列非空,出队,返回1;
否则,提示,返回0 
*/
int deQueue(LinkQueue *Q,ElemType *e)
{
    DataNode *t;
    
    if(Q->front!=NULL||Q->rear!=NULL)//非空
    {
        //1.让t指向队头元素节点
        t=Q->front;
        //2.把队头元素存储到*e中
        *e=t->data;
        //3.删除队头元素节点
        if(Q->front->next==NULL)//只有1个元素
        {
            /*只有1个元素*/
            Q->front=NULL;
            Q->rear=NULL;
        } 
        else
        {
            /*多于1个元素*/
            Q->front=t->next;
        }    
        //4.释放t所占的存储空间
        free(t); 
        return 1;
    } 
    else
    {
        printf("队空,不能出队!\n");
        return 0;
    }    

//销毁队列,删除所有链队节点和数据节点

void DestroyQueue(LinkQueue *Q)
{
    ElemType e;    
    while(Q->front!=NULL||Q->rear!=NULL)//非空
    {
        //出队
        deQueue(Q,&e); 
    } 
    free(Q);
}

//判断队列为空
 /*链式队列中,判断队列是否为空,只需要判断q->front==NULL && q->rear==NULL的条件成立即可*/
int QueueEmpty(LinkQueue *Q)
{
    if(Q->front==NULL && Q->rear==NULL)
    {
        return 1;
    }
    else
    {
        return 0;
    }

//入队操作
/*构造一个节点t,data域存储e,next域存储NULL,若原链队为空,
则将链队结点的两个域都指向结点t,否则将结点t链接到单链表末尾,
并让链队结点的rear域指向它*/
void EnQueue(LinkQueue *Q,ElemType e)
{
    DataNode *t;
    //1.构造一个节点t,data域存储e,next域存储NULL
    t=(DataNode *)malloc(sizeof(DataNode));
    t->data=e;
    t->next=NULL;
    //2.添加 
    if(Q->front!=NULL||Q->rear!=NULL)//非空
    {
        /*队非空*/
        Q->rear->next=t;
        Q->rear=t;
    } 
    else
    {
        /*队空 */
        Q->front=t;
        Q->rear=t;
    }     

//求队列长度
/*
求链式队列的长度 
*/
int lenghtLinkQueue(LinkQueue *Q)
{
    int len;
    if (QueueEmpty(Q))
     {
          len = 0;
         return len;
    }
    DataNode *t;
    //1.构造一个节点t,让它指向队首元素front 
    t=(DataNode *)malloc(sizeof(DataNode));
    t=Q->front;
    len = 1;
    while(t->next != NULL)
    {
        len++;
        t = t->next;
    }
    return len;

//打印队列中的元素
void DispQueue(LinkQueue *Q)
{
    DataNode *p; 
    p=Q->front;
    printf("队列元素为:");
    while(p!=NULL)
    {
        printf("%d ",p->data);
        p=p->next;
    }
    printf("\n");
}
//根据下标插入元素,下标从1开始
 int Insertdata(LinkQueue* Q,int count,ElemType e){
     if(QueueEmpty(Q)){
         printf("队列为空,插入失败。\n");
         return 0;                            //插入失败,返回0
    }
     DataNode* p = Q->front;
     DataNode* f = (DataNode *)malloc(sizeof(DataNode));
     f->data = e;
     if(count == 1){                 //如果插入元素的下标为1,先让插入元素的指针域指向队列头指针,再让队列头指针等于插入元素的节点
         f->next = p;
         Q->front = f;
         return 1;
    }
     for(int i = 1;i < count-1;i++){         //先让数据指针p指向要插入元素下标的上一个节点
         p = p->next;
    }
    f->next = p->next;                      //先让插入元素的指针域指向数据指针的指针域,再让数据指针的指针域指向插入元素的节点,
    p->next = f;
    if(count ==lenghtLinkQueue(Q)+1)        //如果插入元素的下标为队列的最末尾,让队列尾指针指向插入元素的节点
    Q->rear = f;
    return 1;                               //成功删除,返回1
}

//根据下标删除元素,下标从1开始
int Deletedata(LinkQueue* Q,int count){
     if(QueueEmpty(Q)){
         printf("队列为空,删除失败。\n");
         return 0;                          //插入失败,返回0
    }    
    DataNode *p = Q->front,*temp = NULL;   //用p指向当前队列头指针的节点
     if(count == 1){
         Q->front = Q->front->next;         //如果要删除第一个元素,将队列头指针指向下一个节点
         free(p);                           //释放之前头结点的空间
         return 1;                          //成功删除,返回1
    }    
     for(int i = 1;i < count-1;i++){        //将指针p指向要删除元素的上一个节点
         p = p->next;
    }    
    temp = p->next;                        //用temp存储删除元素的指针
    p->next=p->next->next;                 //p的指针域指向删除元素的指针域
    free(temp);                            //释放空间
    if(count == lenghtLinkQueue(Q)) Q->rear = p;      //如果删除的元素为最后一个元素,将队列尾指针指向p,此时p指向的节点为队列最后一个元素
    return 1;                               //成功删除,返回1
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值