队列的实现与简单应用

在上一篇文章中我们讲了线性表,并介绍了线性表的两种实现也就是顺序表与链表,这篇文章我们来介绍一下队列这种数据结构。

不论是队列还是栈,都是对线性表进行一些操作上的限制,队列是从尾进从头出的,也就是先进先出。

队列也有两种实现的方式,顺序队列与链队列。

顺序队列

顺序队列就是利用顺序存储结构实现的队列,下面我们来介绍一下具体实现:

1.结构体定义:

typedef struct queue
{
    int *data; //数据域
    int front,rear,length; //队首队尾标志,队列最大长度
}Queue;

 2.队列初始化:

void init(Queue *q,int length)
{
    q->data = (int*)malloc(sizeof(int) * length); //申请数据空间
    q->front = 0; //队首标志置0,指向第一个元素
    q->rear = -1; //队尾指针置-1,便于入队的操作
    q->length = length; //获取队列最大长度
}

3.顺序队列的简单应用:

1)判断队是否为空:

int empty(Queue *q)
{
    return q->front > q->rear; //如果队首标志大于队尾标志则说明队空,返回1,否则返回0
}

2)入队:

int push(Queue *q,int x)
{
    if(q->rear + 1 >= q->length) //如果队尾标志加1大于或等于最大队列长度,则证明队列已经满了,不能再继续入队
    {
        printf("queue is full,can't insert element %d
",x);
        return 0;
    }
    q->rear++; //队尾标志右移
    q->data[q->rear] = x; //元素入队
    return 1;
}

3)出队:

int pop(Queue *q)
{
    int rem_element = q->data[q->front]; //获取并保存队首元素
    q->front++; //队首标志右移,表示元素已出队
    return rem_element; //返回队首元素
}

4)返回队首元素:

int get_front_element(Queue *q)
{
    return q->data[q->front];
}

5)获取当前队列长度:

int get_queue_length(Queue *q)
{
    return q->rear - q->front + 1;
}

 4.销毁队列:

void destory_queue(Queue *q)
{
    free(q->data);
    free(q);
}

链队列

上面介绍了顺序存储的队列,下面我们来介绍一下链式存储的队列:

1.结点与指针的定义:

typedef struct ptr
{
    Queue *front,*rear; //队首,队尾指针
    int length; //当前队列长度
}QueuePtr;

2.初始化:

void init(QueuePtr *q)
{
    q->front = (Queue*)malloc(sizeof(Queue)); //申请队头结点
    q->rear = q->front; // 初始化队首与队尾指针
    q->front->next = NULL; //对头结点指针置空
}

3.链队列的简单应用

 1)入队:

void push(QueuePtr *q,int x)
{
    Queue *s = (Queue*)malloc(sizeof(Queue)); //申请一个新的结点
    s->data = x;
    s->next = NULL;
    q->rear->next = s; //尾插法
    q->rear = s;
    q->length++; //更新当前队列长度
}

2)出队:

int pop(QueuePtr *q)
{
    if(q->front == q->rear) //判断队空
    {
        printf("queue is empty!
");
        return 0;
    }
    int rem_element = q->front->next->data; //要出队的元素
    Queue *p = q->front;
    q->front = q->front->next; //头指针后移
    free(p);
    q->length--; //更新当前队列长度
    return rem_element;
}

3)返回队首元素:

int get_front_element(QueuePtr *q)
{
    if(q->front == q->rear)
    {
        printf("queue is empty!
");
        return 0;
    }
    return q->front->next->data;
}

4)获取当前队长:

int get_length(QueuePtr *q)
{
    if(q->front == q->rear)
    {
        printf("queue is empty!
");
        return 0;
    }
    return q->length;
}

5)打印队列:

void print_queue(QueuePtr *q)
{
    Queue *p = q->front->next;
    while(p != NULL)
    {
        printf("%d ",p->data);
        p = p->next;
    }
    putchar('
');
}

4.销毁队列:

void destroy_queue(QueuePtr *q) //销毁队列
{
    while(q->front != NULL) //从头结点开始释放队列中所有结点
    {
        q->rear = q->front->next;
        free(q->front);
        q->front = q->rear;
    }
}

队列还有其他很多形式如循环队列,双端队列,优先队列等,在后面会有专题介绍。

原文地址:https://www.cnblogs.com/JLNU-CN/p/12238523.html