用循环单链表来表示队列

来源:互联网 发布:linux 锁机制 编辑:程序博客网 时间:2024/06/03 03:42

  假设用一个循环单链表来表示队列,并且只设置一个指针rear指向队尾结点,但不设置头指针,设计出相应的初始化、入队、出队和判断队列是否为空的算法。
  方法一:使用不带头结点的循环单链表
  1.1)队空条件 rear==NULL
  1.2) 入队, 在*rear结点之后插入结点,并让rear指向该结点
  1.3) 出队,删除*rear结点之后的一个结点
 如图(1)所示:  

这里写图片描述
图(1) 不带头结点的循环单链表,插入结点

 代码如下:  

/*-------------一、不带头结点的循环单链表示队列------------------------*/void InitQu(QNode *&rear){    rear=NULL;}//入队void EnQu(QNode *&rear,ElemType x){    QNode *s;    s=(QNode *)malloc(sizeof(QNode));    s->data=x;    if (rear==NULL)  //队列为空    {        s->next=s;        rear=s;    }    else{      //队列不为空        s->next=rear->next;        rear->next=s;        rear=s;    }}//出队int DeQu(QNode *&rear,ElemType &x){    QNode *q;    if(rear==NULL)        return 0;    else if (rear->next == rear)    {        x=rear->data;        free(rear);        rear=NULL;    }    else{        q=rear->next;        x=q->data;        rear->next=q->next;        free(q);    }    return 1;}//判断队列是否为空int QuEmpty(QNode *rear){    return (rear==NULL);}

  方法二:使用带头结点的循环单链表
  2.1) 队空条件 rear->next == rear
  2.2) 入队, 在*rear结点之后插入结点并让rear指向该结点
  2.3) 出队, 删除rear->next结点之后的一个结点
  如图(2)所示:  

这里写图片描述
图(2) 带头结点的循环单链表,删除结点

  代码如下:  

void InitQu1(QNode *&rear){    rear=(QNode *)malloc(sizeof(QNode));    rear->next=rear;}//进队void EnQu1(QNode *&rear,ElemType x){    QNode *s;    s=(QNode *)malloc(sizeof(QNode));    s->next=NULL;    s->data=x;    s->next=rear->next;    rear->next=s;    rear=s;}//出队int DeQu1(QNode *&rear,ElemType &x){    QNode *q;    if(rear->next==rear)        return 0;    else if(rear->next->next==rear){        x=rear->data;        q=rear->next;        q->next=q;        free(rear);        rear=q;        return 1;    }    else{        q=rear->next->next;        x=q->data;        rear->next->next=q->next;        free(q);        return 1;    }}int QuEmpty1(QNode *rear){    return (rear->next==rear);}

//duiLie.cpp
完整代码如下:

#include <stdio.h>#include <malloc.h>typedef int ElemType;typedef struct qnode{ //数据结点    ElemType data;    struct qnode *next;}QNode;typedef struct{ //链队定义    QNode *front;    QNode *rear;}LiQueue;/*-------------一、不带头结点的循环单链表示队列---------------*/void InitQu(QNode *&rear){    rear=NULL;}//入队void EnQu(QNode *&rear,ElemType x){    QNode *s;    s=(QNode *)malloc(sizeof(QNode));    s->data=x;    if (rear==NULL)  //队列为空    {        s->next=s;        rear=s;    }    else{      //队列不为空        s->next=rear->next;        rear->next=s;        rear=s;    }}//出队int DeQu(QNode *&rear,ElemType &x){    QNode *q;    if(rear==NULL)        return 0;    else if (rear->next == rear)    {        x=rear->data;        free(rear);        rear=NULL;    }    else{        q=rear->next;        x=q->data;        rear->next=q->next;        free(q);    }    return 1;}//判断队列是否为空int QuEmpty(QNode *rear){    return (rear==NULL);}/*-------------------二、用带头结点的循环单链表表示队列------------------*/void InitQu1(QNode *&rear){    rear=(QNode *)malloc(sizeof(QNode));    rear->next=rear;}//进队void EnQu1(QNode *&rear,ElemType x){    QNode *s;    s=(QNode *)malloc(sizeof(QNode));    s->next=NULL;    s->data=x;    s->next=rear->next;    rear->next=s;    rear=s;}//出队int DeQu1(QNode *&rear,ElemType &x){    QNode *q;    if(rear->next==rear)        return 0;    else if(rear->next->next==rear){        x=rear->data;        q=rear->next;        q->next=q;        free(rear);        rear=q;        return 1;    }    else{        q=rear->next->next;        x=q->data;        rear->next->next=q->next;        free(q);        return 1;    }}int QuEmpty1(QNode *rear){    return (rear->next==rear);}//不带头结点的循环单链表输出void DispQueueR(QNode *&rear){    if(rear==NULL)        return;    QNode *p=rear->next;    do{        printf("%d ",p->data);        p=p->next;    }while(p!=rear->next);    printf("\n");}//带头结点的循环单链表输出void DispQueueR2(QNode *&rear){    if (rear->next == rear)        return;    QNode *q=rear->next->next;    while(q!=rear){        printf("%d ",q->data);        q=q->next;    }    if (q==rear)    {        printf("%d ",q->data);    }    printf("\n");}void main(){    QNode *p;    //不带头结点的循环单链表//  InitQu(p);//  int i=0;//  for (i=1;i<10;i++)//  {//      EnQu(p,i*i-1);//  }//  DispQueueR(p);    //带头结点的循环单链表    InitQu1(p);    int j=0;    for (j=1;j<10;j++)    {        EnQu1(p,j*j-1);    }    DispQueueR2(p);}

效果如下:

这里写图片描述

1 0
原创粉丝点击