C语言数据结构之栈和队列的实现及应用

C语言数据结构之栈和队列的实现及应用

什么是栈和队列?

栈是一种具有后进先出(LIFO)特性的线性数据结构,可以理解为一个只能在一端进行插入和删除操作的数据结构。通常称插入元素的一端为栈顶,删除元素的一端为栈底。

队列是一种具有先进先出(FIFO)特性的线性数据结构,可以理解为一个只能在两端进行插入和删除操作的数据结构。一端进行插入操作,称之为队尾,一端进行删除操作,称之为队首。

栈的实现及应用

栈的实现

在C语言中实现栈用数组和链表两种方式。下面我们讨论数组实现方式。

首先需要定义一个数组和一个指针,指针指向栈顶元素。实现push和pop操作时,修改指针位置并操作数组内容即可。

#define MAX_SIZE 1000

typedef struct {
    int a[MAX_SIZE];
    int top;
} Stack;

void push(Stack *s, int x) {
    if(s->top < MAX_SIZE) {
        s->a[s->top++] = x;
    } else {
        printf("Stack overflow!\n");
    }
}

int pop(Stack *s) {
    if(s->top > 0) {
        return s->a[--s->top];
    } else {
        printf("Stack underflow!\n");
        return -1;
    }
}

栈的应用

常见的栈的应用场景有表达式求值、括号匹配、迷宫问题等,下面我们简单介绍两个示例。

示例1:表达式求值

算术表达式通常是用中缀表示,即操作数在中间,操作符在两侧。为了求值表达式,我们通常将中缀表达式转成后缀表达式,然后用栈求值。下面是示例代码:

int getPrior(char op) {
    if(op == '+' || op == '-') {
        return 1;
    }
    if(op == '*' || op == '/') {
        return 2;
    }
    if(op == '(' || op == ')') {
        return 0;
    }
    return -1;
}

int isOp(char c) {
    return c == '+' || c == '-' || c == '*' || c == '/' || c == '(' || c == ')';
}

void infix2postfix(char *infix, char *postfix) {
    Stack s;
    s.top = 0;
    int i, j;
    for(i = 0, j = 0; infix[i]; i++) {
        if(!isOp(infix[i])) {
            postfix[j++] = infix[i];
        } else if(infix[i] == ')') {
            while(s.top && s.a[s.top-1] != '(') {
                postfix[j++] = s.a[--s.top];
            }
            if(s.top) {
                s.top--;
            }
        } else {
            while(s.top && getPrior(s.a[s.top-1]) >= getPrior(infix[i])) {
                postfix[j++] = s.a[--s.top];
            }
            s.a[s.top++] = infix[i];
        }
    }
    while(s.top) {
        postfix[j++] = s.a[--s.top];
    }
    postfix[j] = '\0';
}

int postfixEval(char *postfix) {
    Stack s;
    s.top = 0;
    int i, a, b, c;
    for(i = 0; postfix[i]; i++) {
        if(!isOp(postfix[i])) {
            push(&s, postfix[i] - '0');
        } else {
            a = pop(&s);
            b = pop(&s);
            switch(postfix[i]) {
                case '+':
                    c = a + b;
                    break;
                case '-':
                    c = b - a;
                    break;
                case '*':
                    c = a * b;
                    break;
                case '/':
                    c = b / a;
                    break;
            }
            push(&s, c);
        }
    }
    return pop(&s);
}

示例2:括号匹配

括号匹配问题也可以使用栈来解决。我们遍历字符串,并用栈记录左括号,遇到右括号时出栈一个左括号并匹配,如果不匹配直接返回。

int isMatch(char a, char b) {
    return (a == '(' && b == ')') || (a == '[' && b == ']') || (a == '{' && b == '}');
}

int isBalanced(char *s) {
    Stack stk;
    stk.top = 0;
    int i;
    for(i = 0; s[i]; i++) {
        if(s[i] == '(' || s[i] == '[' || s[i] == '{') {
            push(&stk, s[i]);
        } else if(s[i] == ')' || s[i] == ']' || s[i] == '}') {
            if(!stk.top || !isMatch(stk.a[stk.top-1], s[i])) {
                return 0;
            }
            stk.top--;
        }
    }
    return stk.top == 0;
}

队列的实现及应用

队列的实现

在C语言中实现队列用数组和链表两种方式。下面我们讨论数组实现方式。

与栈相似,需要定义一个数组和两个指针,一个指向队头元素,一个指向队尾元素。实现enqueue和dequeue操作时,修改指针位置并操作数组内容即可。

#define MAX_SIZE 1000

typedef struct {
    int a[MAX_SIZE];
    int front, rear;
} Queue;

void enqueue(Queue *q, int x) {
    if(q->rear < MAX_SIZE) {
        q->a[q->rear++] = x;
    } else {
        printf("Queue overflow!\n");
    }
}

int dequeue(Queue *q) {
    if(q->front < q->rear) {
        return q->a[q->front++];
    } else {
        printf("Queue underflow!\n");
        return -1;
    }
}

队列的应用

常见的队列的应用场景有FIFO算法、消息队列、排队系统等,下面我们简单介绍两个示例。

示例1:FIFO算法

FIFO(First In First Out)算法是一种页面置换算法,也称先进先出算法。它选择最早调入内存的页面进行置换。

#define MEM_SIZE 4

int pageFaults(int *references, int n) {
    Queue q;
    q.front = q.rear = 0;
    int mem[MEM_SIZE] = {0};
    int i, j, faults = 0;
    for(i = 0; i < n; i++) {
        int found = 0;
        for(j = 0; j < MEM_SIZE; j++) {
            if(references[i] == mem[j]) {
                found = 1;
                break;
            }
        }
        if(found) {
            // already in memory
        } else if(q.rear < MEM_SIZE) {
            mem[q.rear++] = references[i];
            enqueue(&q, references[i]);
            faults++;
        } else {
            int top = dequeue(&q);
            for(j = 0; j < MEM_SIZE; j++) {
                if(mem[j] == top) {
                    mem[j] = references[i];
                    break;
                }
            }
            enqueue(&q, references[i]);
            faults++;
        }
    }
    return faults;
}

示例2:消息队列

消息队列是一种异步通信机制,常用于进程间通信。一个进程将消息发送到队列,另一个进程从队列中读取消息。

#define MAX_SIZE 1000

typedef struct {
    int queue[MAX_SIZE];
    int front, rear;
    pthread_mutex_t mutex;
    pthread_cond_t notEmpty, notFull;
} MsgQueue;

void initMsgQueue(MsgQueue *q) {
    q->front = q->rear = 0;
    pthread_mutex_init(&q->mutex, NULL);
    pthread_cond_init(&q->notEmpty, NULL);
    pthread_cond_init(&q->notFull, NULL);
}

void sendMsg(MsgQueue *q, int msg) {
    pthread_mutex_lock(&q->mutex);
    while(q->rear - q->front >= MAX_SIZE) {
        pthread_cond_wait(&q->notFull, &q->mutex);
    }
    q->queue[q->rear++ % MAX_SIZE] = msg;
    pthread_mutex_unlock(&q->mutex);
    pthread_cond_signal(&q->notEmpty);
}

int recvMsg(MsgQueue *q) {
    int msg;
    pthread_mutex_lock(&q->mutex);
    while(q->rear <= q->front) {
        pthread_cond_wait(&q->notEmpty, &q->mutex);
    }
    msg = q->queue[q->front++ % MAX_SIZE];
    pthread_mutex_unlock(&q->mutex);
    pthread_cond_signal(&q->notFull);
    return msg;
}

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:C语言数据结构之栈和队列的实现及应用 - Python技术站

(0)
上一篇 2023年5月17日
下一篇 2023年5月17日

相关文章

  • Redis高效率原因及数据结构分析

    Redis高效率原因及数据结构分析 Redis高效率的原因 Redis是一款高性能、高可靠性的内存数据库,其高效率的原因主要体现在以下几个方面: 1. 内存存储 Redis数据完全存储在内存中,而不是像传统的关系型数据库一样存储在磁盘中。内存的读写速度要远远快于磁盘的读写速度,因此Redis在数据读写时的速度非常快,能够达到每秒钟数百万次的读写操作。 2. …

    数据结构 2023年5月17日
    00
  • 环形队列的实现 [详解在代码中]

    1 package DataStructures.Queue.Array.Exerice; 2 3 /** 4 * @author Loe. 5 * @project DataStructures&Algorithms 6 * @date 2023/5/8 7 * @ClassInfo 环形队列 8 * 主要使用取模的特性来实现环形特征 9 */ 1…

    算法与数据结构 2023年5月8日
    00
  • 数据结构 双机调度问题的实例详解

    数据结构:双机调度问题的实例详解 本文主要讲解数据结构中双机调度问题的实例详解,涉及到相关的算法和代码实现。双机调度问题是指如何安排多个任务在两台机器上执行,使得两台机器的工作时间尽可能相等,从而达到最优的调度效果。 1. 问题分析 假设有 $n$ 个任务,每个任务的执行时间分别为 $t_1, t_2, …, t_n$,需要按照某种调度方案分配给两台机器…

    数据结构 2023年5月17日
    00
  • 2021最新Android笔试题总结美团Android岗职能要求

    2021最新Android笔试题总结和美团Android岗职能要求 简介 本文主要介绍了2021最新的Android笔试题总结和美团Android岗职能要求,旨在为正在面试美团Android岗位的面试者提供参考。 笔试题总结 下面是近期美团Android面试中出现的一些笔试题目: 1. 请描述Android中BroadcastReceiver的生命周期。 安…

    数据结构 2023年5月17日
    00
  • 2021年最新Redis面试题汇总(1)

    下面我将为您详细讲解“2021年最新Redis面试题汇总(1)”的完整攻略。 1. Redis概述 首先,我们需要了解Redis是什么,以及它的特点和应用场景。 1.1 什么是Redis Redis是一种内存中的数据结构存储,可以用作数据库、缓存和消息中间件。它支持多种数据结构,如字符串、哈希、列表、集合和有序集合,并提供了丰富的功能,如事务、持久化、Lua…

    数据结构 2023年5月17日
    00
  • Python数据结构之栈详解

    Python数据结构之栈详解 什么是栈? 栈(stack)是一种数据元素只能在一端进行插入和删除操作的线性表。 栈的特点是后进先出,即在一个非空栈中,最后放入的元素最先被取出。 栈的操作 栈操作的基本有两个: push(elem):插入一个新的元素elem到栈中。 pop():弹出栈顶的元素,并返回这个被弹出元素的值。 此外还有一个用于查询栈顶元素的操作: …

    数据结构 2023年5月17日
    00
  • C++实现数据结构的顺序表详解

    C++实现数据结构的顺序表详解 介绍 在进行程序开发时,常常需要对数据进行存储和操作。其中一种数据结构是顺序表,它提供了一种在内存中线性存储数据的方法,能够方便地对数据进行插入、删除、查找等操作。本文将详细介绍如何使用C++实现数据结构的顺序表,帮助读者掌握顺序表的创建、插入、删除、查找等操作。 创建顺序表 顺序表可以使用数组来实现。下面的代码展示了如何创建…

    数据结构 2023年5月17日
    00
  • 一步步带你学习设计MySQL索引数据结构

    一步步带你学习设计MySQL索引数据结构 索引原理 在MySQL中,索引是一种数据结构,用于快速查找表中的记录。在一张表中,可以使用不同的列来创建索引,索引可以大大提高查询效率,减少扫描行数,加快数据查询速度。 索引的实现一般使用的是B树和B+树这两种数据结构,因为它们都具有良好的平衡性,可以快速查找,插入和删除。 如何设计MySQL索引 确认需要优化的查询…

    数据结构 2023年5月17日
    00
合作推广
合作推广
分享本页
返回顶部