数据结构之 队列(C语言实现)

数据结构之 队列(C语言实现)

1. 队列ADT

1.1 介绍

队列(queue)属于表,使用队列时插入在一端进行而删除在另一端进行。

1.2 队列模型

队列的基本操作是Enqueue(入队),它是在表的末端(队尾(rear))插入一个元素,还有Dequeue(出队),它是删除(或返回)在表的开头(队头(front))的元素。如下图:

这里写图片描述

2. 队列的数组实现

  • queue.h文件
#ifndef _QUEUE_H_
#define _QUEUE_H_

#define MinQueueSize    5   //最小队列元素

typedef int elementType;

typedef struct queueRecord
{
    int capacity;   //队列的最大容量
    int front;  //队首元素下标
    int rear;   //队尾元素下标
    int size;   //队列有多少元素
    elementType *array; //指向动态分配的内存
}QUEUE;

int isEmpty(QUEUE *q);      //判空
int isFull(QUEUE *q);       //判满
QUEUE *createQueue(int maxElements);    //创建一个队列
void disposeQueue(QUEUE *q);    //销毁一个队列
void makeEmpty(QUEUE *q);   //构造一个空队列
void enQueue(elementType element, QUEUE *q);    //入队
elementType front(QUEUE *q);        //返回队首元素但不删除
void deQueue(QUEUE *q); //删除队首元素不返回
elementType frontAndDequeue(QUEUE *q);  //出队,返回并删除

#endif
  • queue.c文件
#include <stdio.h>
#include <stdlib.h>
#include "queue.h"

int isEmpty(QUEUE *q)
{
    return (q->size == 0);
}
int isFull(QUEUE *q)
{
    return (q->size == q->capacity);
}
QUEUE *createQueue(int maxElements)
{
    if(maxElements < MinQueueSize) {
        printf("queue size is too small\n");    
        return NULL;
    } else {
        QUEUE *q = (QUEUE *)malloc(sizeof(struct queueRecord));
        q->array = (elementType *)malloc(sizeof(elementType) * maxElements);
        q->capacity = maxElements;
        makeEmpty(q);
        return q;
    }
}
void disposeQueue(QUEUE *q)
{
    if(q != NULL) {
        free(q->array); 
        free(q);
    }   
}
void makeEmpty(QUEUE *q)
{
    if(q != NULL) {
        q->front = 1;   
        q->rear = 0;
        q->size = 0;
    }
}
static int succ(int value, QUEUE *q) 
{
    if(++value == q->capacity) 
        value = 0;
    return value;
}
void enQueue(elementType element, QUEUE *q)
{
    if(!isFull(q)) {
        q->size++;  
        q->rear = succ(q->rear, q);
        q->array[q->rear] = element;
    } else {
        printf("Full queue\n"); 
    }
}
elementType front(QUEUE *q)
{
    if(!isEmpty(q)) {
        return q->array[q->front];  
    } else {
        printf("empty queue\n");    
    }
}
void deQueue(QUEUE *q)
{
    if(!isEmpty(q)) {
        q->size--;
        q->front = succ(q->front, q);
    } else {
        printf("empty queue\n");    
    }
}
elementType frontAndDequeue(QUEUE *q)
{
    if(!isEmpty(q)) {
        int ret = q->array[q->front];
        q->size--;
        q->front = succ(q->front, q);
        return ret; 
    } else {
        printf("empty queue\n");    
        return 0;
    }
}
#include #include #include //队列最大长度 #define MAX_QUEUE 1024 //偷懒,就用静态队列了 static int mQueue[MAX_QUEUE]; //队列插入 void InsertData(int **Front, int **Rear) { if (*Rear + 1 == *Front && (*Rear + 1 - MAX_QUEUE != *Front)) { //当队列数据已满,返回 puts("Queue Size Overflow!\n"); return; } else if (*Rear - mQueue > MAX_QUEUE) { //实现的是类似循环队列,但由于是静态线性队列(数组) //而不是用链表来实现的,所以到静态队列(数组)尾部,尾指针自动指向(数组)头部 *Rear = mQueue; } puts("Input Data:"); scanf("%d", *Rear); //输入数据后,尾指针后移 *Rear += 1; } //从头指针删除一个队列中的数据 void DeleteData(int **Front, int **Rear) { if (*Front == *Rear) { //头指针尾指针重合,队列空,不能删除,返回 puts("Queue Empty!\n"); return; } else if (*Front - mQueue > MAX_QUEUE) { //参考 Rear *Front = mQueue; } //从头指针删除一个数据 *Front += 1; } //显示队列数据 void ShowData(int **Front, int **Rear) { int *temp; for (temp=*Front; temp!=*Rear; temp++) { printf("%d --> ", *temp); } puts("\n"); } void usage(void) { puts("1. Insert Data"); puts("2. Delete Data"); puts("3. Show Data"); } int main(int argc, char **argv) { //头指针,尾指针 //队列的一个特性 First in first out FIFO int *pFront, *pRear; int op_code; //初始化队列,头指针和尾指针此时指向的地址相同 pFront = pRear = mQueue; while (1) { usage(); scanf("%d", &op_code); switch (op_code) { case 1: printf("%p\n", pFront); printf("%d\n", *pFront); InsertData(&pFront, &pRear); break; case 2: DeleteData(&pFront, &pRear); break; case 3: ShowData(&pFront, &pRear); break; default: break; } } return 0; }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值