データ構造キューの基本操作とメニュー適用(Cプログラム実装)

//参考書は、Machinery Industry Pressのデータ構造とアルゴリズム分析です(C言語の説明)。

//キューの実装には2つのパッケージがあり、比較後に実行する必要があります。

// 2つのキューは異なる方法で実装されますが、テストプログラムは同じメインプログラムであり、移植性が高くなっています。

//このプログラムは移植性プログラムです。

// Linux / Mac os / Windowsでコンパイルして実行できます。

//欠点がある場合は、それを上げてください。ブロガーは最善を尽くして修正します。

//役に立つ場合は、収集したり、他の人と共有したりしてください。

//盗用および許可なく転載することは固く禁じられています。

//ソースコードはこちらです。刺激を受けたいと思います。

// ------------------------------------------------ ----------------------------
//main.c

#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include "queue.h"

int show_menu(void);            //显示主菜单;
int get_first(void);            //获取用户输入的第1个字符;
void eatline(void);             //清空输入缓冲区;
elemtype input(void);           //获取用户输入的数据元素;
void choice(int ch, queue *qe); //操作循环队列中的数据元素;

int main(void)
{
    
    
    int ch;
    queue qe;

    init_queue(&qe);
    while ((ch = show_menu()) != 'q')
    {
    
    
        choice(ch, &qe);
    }
    destroy_queue(&qe);
    puts("本程序完成!");

    return 0;
}

int show_menu(void)
{
    
    
    int ch;

    puts("========================================");
    puts("a) 判断队列是否为空");
    puts("b) 查看队列当前长度");
    puts("c) 获取队头数据元素");
    puts("d) 添加一个数据元素至队列中");
    puts("e) 令队头数据元素出队");
    puts("f) 遍历队列");
    puts("q) 退出本程序");
    puts("========================================");
    printf("请您输入选择: ");
    while (ch = get_first(), strchr("abcdefq", ch) == NULL)
    {
    
    
        printf("您的选择无效!请重新输入:");
    }
    return ch;
}

int get_first(void)
{
    
    
    int ch;

    do
    {
    
    
        ch = tolower(getchar());
    } while (isspace(ch));
    eatline();

    return ch;
}

void eatline(void)
{
    
    
    while (getchar() != '\n')
        continue;
    return;
}

elemtype input(void)
{
    
    
    elemtype value;

    printf("请您输入一个数据元素(整型元素):");
    while (scanf("%d", &value) != 1)
    {
    
    
        eatline();
        printf("数据无效!请重新输入:");
    }
    eatline();
    return value;
}

void choice(int ch, queue *qe)
{
    
    
    elemtype val;

    switch (ch)
    {
    
    
    case 'a':
    {
    
    
        printf("此队列%s!\n", isempty(qe) ? "为空" : "非空");
        break;
    }
    case 'b':
    {
    
    
        printf("当前队列中数据元素个数: %d个\n", queue_length(qe));
        break;
    }
    case 'c':
    {
    
    
        val = get_front_value(qe);
        if (val != -1)
        {
    
    
            printf("队头数据元素是: %d\n", val);
        }
        break;
    }
    case 'd':
    {
    
    
        val = input();
        enqueue(qe, val);
        break;
    }
    case 'e':
    {
    
    
        dequeue(qe);
        break;
    }
    case 'f':
    {
    
    
        if (isempty(qe))
        {
    
    
            printf("此队列为空!无法进行遍历!\n");
            break;
        }
        traverse(qe);
        break;
    }
    }
    printf("\n\n\n\n\n\n\n\n\n\n\n\n");
    return;
}

//queue(array).h

#ifndef QUEUE_H_
#define QUEUE_H_
#include <stdbool.h>
#define MAXSIZE 10

typedef int elemtype;

typedef struct
{
    
    
    elemtype *base; //队列数组;
    int front;      //队头指针;
    int rear;       //队尾指针;
    int capacity;   //队列总长度;
} queue;

//1) 构造一个空队列;
void init_queue(queue *qe);
/*----------------------------------------------------------------------*/

//2) 销毁队列存储空间;
void destroy_queue(queue *qe);
/*----------------------------------------------------------------------*/

//3) 判断队列是否为空;
bool isempty(queue *qe);
/*----------------------------------------------------------------------*/

//4) 判断队列是否为满;
bool isfull(queue *qe);
/*----------------------------------------------------------------------*/

//5) 获取队列的当前数据元素个数;
int queue_length(queue *qe);
/*----------------------------------------------------------------------*/

//6) 若队列非空则获取其队头数据元素;
elemtype get_front_value(queue *qe);
/*----------------------------------------------------------------------*/

//7) 添加一个数据元素到队尾;
void enqueue(queue *qe, elemtype val);
/*----------------------------------------------------------------------*/

//8) 若队列非空则令队头元素出队;
void dequeue(queue *qe);
/*----------------------------------------------------------------------*/

//9) 若队列非空则遍历其中数据元素;
void traverse(queue *qe);
/*----------------------------------------------------------------------*/

#endif

//queue(array).c

#include <stdio.h>
#include <stdlib.h>
#include "queue.h"

void init_queue(queue *qe)
{
    
    
    qe->base = (elemtype *)malloc(sizeof(elemtype));
    if (NULL == qe->base)
    {
    
    
        fprintf(stderr, "动态内存分配失败!本程序退出!\n");
        exit(EXIT_FAILURE);
    }
    qe->front = qe->rear = 0;
    qe->capacity = MAXSIZE;
    return;
}

void destroy_queue(queue *qe)
{
    
    
    free(qe->base);
    return;
}

bool isempty(queue *qe)
{
    
    
    return qe->front == qe->rear;
    //头尾指针指向同一个元素即可认为队列为空;
}

bool isfull(queue *qe)
{
    
    
    return qe->front == (qe->rear + 1) % qe->capacity;
    //少用一个元素空间,即可认为队列已满;
}

int queue_length(queue *qe)
{
    
    
    return (qe->rear - qe->front + qe->capacity) % qe->capacity;
    //循环队列尾指针和头指针的差值可能为负数;
    //因此需要加上队列容量的最大长度后取余即可得出当前队列中的元素个数;
}

elemtype get_front_value(queue *qe)
{
    
    
    if (!isempty(qe))
    {
    
    
        return qe->base[qe->front];
    }
    printf("空队列!无法获取队头元素!\n");
    return -1;
}

void enqueue(queue *qe, elemtype val)
{
    
    
    if (isfull(qe))
    {
    
    
        printf("此队列已满!无法添加数据元素!\n");
        return;
    }
    qe->base[qe->rear] = val;
    qe->rear = (qe->rear + 1) % qe->capacity;
    printf("成功添加数据元素%d至队列!\n", val);
    return;
}

void dequeue(queue *qe)
{
    
    
    if (isempty(qe))
    {
    
    
        printf("此队列为空!无法删除队头元素!\n");
        return;
    }
    printf("队头元素%d出队成功!\n", qe->base[qe->front]);
    qe->front = (qe->front + 1) % qe->capacity;
    return;
}

void traverse(queue *qe)
{
    
    
    int head = qe->front;
    int tail = qe->rear;

    printf("从队头到队尾遍历队列中的数据元素如下:\n");
    while (head < tail)
    {
    
    
        printf("%d ", qe->base[head++]);
    }
    return;
}

//queue(linkedlist).h

#ifndef QUEUE_H_
#define QUEUE_H_
#include <stdbool.h>

typedef int elemtype;

typedef struct node
{
    
    
    elemtype data;
    struct node *next;
} qnode;

typedef struct
{
    
    
    qnode *front; //队头指针;
    qnode *rear;  //队尾指针;
    int size;     //队列元素个数;
} queue;

//1) 构造一个空队列;
void init_queue(queue *qe);
/*----------------------------------------------------------------------*/

//2) 销毁队列存储空间;
void destroy_queue(queue *qe);
/*----------------------------------------------------------------------*/

//3) 判断队列是否为空;
bool isempty(queue *qe);
/*----------------------------------------------------------------------*/

//4) 获取队列的当前数据元素个数;
int queue_length(queue *qe);
/*----------------------------------------------------------------------*/

//5) 若队列非空则获取其队头数据元素;
elemtype get_front_value(queue *qe);
/*----------------------------------------------------------------------*/

//6) 添加一个数据元素到队尾;
void enqueue(queue *qe, elemtype val);
/*----------------------------------------------------------------------*/

//7) 若队列非空则令队头元素出队;
void dequeue(queue *qe);
/*----------------------------------------------------------------------*/

//8) 若队列非空则遍历其中数据元素;
void traverse(queue *qe);
/*----------------------------------------------------------------------*/

#endif

//queue(linkedlist).c

#include <stdio.h>
#include <stdlib.h>
#include "queue.h"

void init_queue(queue *qe)
{
    
    
    qe->front = qe->rear = NULL;
    qe->size = 0;
    return;
}

void destroy_queue(queue *qe)
{
    
    
    while (!isempty(qe))
    {
    
    
        dequeue(qe);
    }
    return;
}

bool isempty(queue *qe)
{
    
    
    return NULL == qe->front;
}

int queue_length(queue *qe)
{
    
    
    return qe->size;
}

elemtype get_front_value(queue *qe)
{
    
    
    if (!isempty(qe))
    {
    
    
        return qe->front->data;
    }
    printf("空队列!无法获取队头元素!\n");
    return -1;
}

void enqueue(queue *qe, elemtype val)
{
    
    
    qnode *new_node = (qnode *)malloc(sizeof(qnode));
    if (NULL == new_node)
    {
    
    
        fprintf(stderr, "动态内存分配失败!本程序退出!\n");
        exit(EXIT_FAILURE);
    }
    new_node->data = val;
    new_node->next = NULL;
    if (isempty(qe))
    {
    
    
        qe->front = new_node; //添加新结点令队头指针指向此结点;
    }
    else
    {
    
    
        qe->rear->next = new_node; //将新结点添加至队尾;
    }
    qe->rear = new_node; //修改队尾指针指向新结点;
    ++qe->size;
    printf("成功添加数据元素%d至队列!\n", val);
    return;
}

void dequeue(queue *qe)
{
    
    
    if (isempty(qe))
    {
    
    
        printf("此队列为空!无法删除队头元素!\n");
        return;
    }
    printf("队头元素%d出队成功!\n", qe->front->data);
    qnode *temp = qe->front;
    qe->front = qe->front->next;
    if (NULL == qe->front)
    {
    
    
        qe->rear = NULL; //重新形成空队列;
    }
    --qe->size;
    free(temp);
    return;
}

void traverse(queue *qe)
{
    
    
    qnode *pos = qe->front;

    printf("从队头到队尾遍历队列中的数据元素如下:\n");
    while (pos != NULL)
    {
    
    
        printf("%d ", pos->data);
        pos = pos->next;
    }
    return;
}

// ------------------------------------------------ ----------------------------

// ----------------------------- 2021年1月13日--------------- ---------------

おすすめ

転載: blog.csdn.net/m0_46181359/article/details/112557520