数据结构2————队的概念和运算

来源:互联网 发布:米思米选型软件2017 编辑:程序博客网 时间:2024/05/20 23:08

数据结构2—————队的概念和运算

一.队的概念

1.定义

  • 栈是一种只允许在一端进行插入,在另一端进行删除的线性表,和栈类似都是一种操作受限的线性表

2. 相关概念

* 队头:允许进行删除的一端称为队顶* 队尾:允许进行插入的一端称为队底* 出队:在队头进行删除操作* 入队:在队尾进行插入操作* 空队:队内没有元素

3. 特点

先进先出。

4.栈的ADT定义

Data    同线性表。元素具有相同的类型,相邻元素具有前驱和后继关系。Operation    InitQueue(*Q):初始化操作,建立一个空队列QDestroyQueue(*Q):若队列Q存在,則销毀它。    ClearQueue(*Q):将队列 Q 清空。    QueueEmpty(Q):若队列Q为空,送回true,否則退回false。    GetHead(Q, *e):若队列Q存在且非空,用e返因队列Q的队头元素。    EnQueue(*Q,e):若队列Q存在,插入新元素e到队列Q中并成为队尾元素。     DeQueue(*Q, *e):刪除队列Q中队头元素,并用e返回其值。     QueueLength(Q):送回队列Q的元素个教。endADT

5. 栈的存储结构

  • 顺序存储结构(循环队列)
  • 链式存储结构(链栈)

6.图示

二.链队列

1.结构定义

#include <stdio.h>#include <stdlib.h>#define TRUE 1#define FALSE 0 typedef int Elemtype;//节点 typedef  struct node{    Elemtype date;    struct node *next;}QNode;//链队的头尾指针typedef struct{    QNode *front;    QNode *rear;}LQueue;

2.说明

  • 用链表作为队的存储形式(非线性存储),靠近头结点一端为队头,另一端为队尾,使用两个指针,一个指向队头,一个指向队尾
  • 空栈情况:指向队头的坐标等于指向队尾的坐标。
  • 入队:创建新的节点,并将它链接到队尾,尾指针移动
  • 出队:先判空,如果不是空栈将头结点的下一个节点删除

3.图示

这里写图片描述

4.初始化

//初始化LQueue *InitLQueue(){    LQueue *qL;    QNode *p;    qL=(LQueue *)malloc(sizeof(LQueue));    p=(QNode *)malloc(sizeof(QNode));    p->next=NULL;    qL->front=qL->rear=p;    return qL; }

5.入队

//入队int InLQueue(LQueue *qL ,Elemtype x){    QNode *p;    p=(QNode *)malloc(sizeof(QNode));    p->date=x;    p->next=NULL;    qL->rear->next=p;    qL->rear=p;    return TRUE; } 

6.判断是否为空

//判空队 int EmptyLQueue(LQueue *qL){    if(qL->front==qL->rear)        return TRUE;    return FALSE;} 

7.出队

//出队int QutLQueue(LQueue *qL ,Elemtype *x){    QNode *p;    if(!EmptyLQueue(qL)){ //栈不空         p=qL->front->next;        *x=p->date;        qL->front->next=p->next;//删除        free(p);        if(qL->front->next ==NULL)            qL->rear = qL->front;        return TRUE;             }    printf("空队\n");     return FALSE; } 

8.链栈的其他方法

  • 可将链表设置为循环链表,只设置尾指针,也可以完成链表的所有操作,具体实现可见我最后代码链接里的代码

三.循环队列

1.结构定义

#include <stdio.h>#include <stdlib.h>#define TRUE 1#define FALSE 0 #define MAXSIZE 10typedef int Elemtype;typedef struct{    Elemtype date[MAXSIZE];    int front,rear; }CSeQeue;

2.说明

  • 循环队列是使用数组作为存储形式(线性存储),开始时靠近下标0为队头,另一端为队尾,之后队尾到达数组的末尾后,如果队头不在0处,那么队尾从靠近0的一端重新开始,形成一个环
  • 这个示例代码中,使用的牺牲一个空间来判断队空,还是队满
  • 队空:队尾==队头
  • 队满:队尾+1 == 队头
  • 入栈:
qS->rear=(qS->rear+1)%MAXSIZE;//计算入对后队尾的位置qS->date[qS->rear]=x;//入队
  • 出栈:
qS->front=(qS->front+1)%MAXSIZE;//计算出队后的队头位置*x = qS->date[qS->front];//出队

3.图示

这里写图片描述

4.初始化

//初始化CSeQeue *InitSeQueue(){    CSeQeue *qS;    qS=(CSeQeue *)malloc(sizeof(CSeQeue));    qS->rear=qS->front=MAXSIZE-1;    return qS;}

5.入队

//入队int InSeQueue(CSeQeue *qS ,Elemtype x){    if((qS->rear+1)%MAXSIZE==qS->front){        printf("队满\n");        return FALSE;    }    qS->rear=(qS->rear+1)%MAXSIZE;    qS->date[qS->rear]=x;    return TRUE;} 

6.判断是否为空

//判空int EmptySeQueue(CSeQeue *qS){    if(qS->front == qS->rear)        return TRUE;    return FALSE;} 

7.出队

//出队 int QutSeQueue(CSeQeue *qS ,Elemtype *x){    if(!EmptySeQueue(qS)){        qS->front=(qS->front+1)%MAXSIZE;        *x = qS->date[qS->front];        return TRUE;    }    printf("队空\n");    return FALSE; } 

8.循环队列的其他实现方法

  • 设置一个标志来判断是队空还是队满
  • 不使用队尾指针,改为长度

四.源码

test2文件夹中

原创粉丝点击