引言

栈是一种先进后出(FILO)的数据结构,广泛应用于程序设计中的各种场景。C语言作为一种经典的编程语言,提供了多种操作栈的方法。本文将从入门到精通的角度,详细介绍C语言中的栈操作,并通过实战笔记帮助读者轻松驾驭数据结构。

第一章:栈的基本概念

1.1 什么是栈?

栈是一种线性数据结构,遵循先进后出的原则。在栈中,元素的添加和删除都只发生在栈顶。

1.2 栈的组成

一个栈由栈顶指针(Top)、栈底指针(Bottom)和栈元素组成。栈顶指针指向栈顶元素,栈底指针指向栈底。

1.3 栈的存储结构

栈可以采用顺序存储结构或链式存储结构。顺序存储结构使用数组实现,链式存储结构使用链表实现。

第二章:C语言栈的顺序存储实现

2.1 顺序栈的定义

顺序栈使用数组存储数据,通过栈顶指针控制栈顶元素。

2.2 顺序栈的基本操作

2.2.1 初始化栈

#define MAX_SIZE 100
typedef struct {
    int data[MAX_SIZE];
    int top;
} SeqStack;
void InitStack(SeqStack *s) {
    s->top = -1;
}

2.2.2 入栈

void Push(SeqStack *s, int x) {
    if (s->top == MAX_SIZE - 1) {
        printf("栈满!\n");
        return;
    }
    s->data[++s->top] = x;
}

2.2.3 出栈

int Pop(SeqStack *s) {
    if (s->top == -1) {
        printf("栈空!\n");
        return 0;
    }
    return s->data[s->top--];
}

2.2.4 获取栈顶元素

int GetTop(SeqStack *s) {
    if (s->top == -1) {
        printf("栈空!\n");
        return 0;
    }
    return s->data[s->top];
}

第三章:C语言栈的链式存储实现

3.1 链栈的定义

链栈使用链表存储数据,通过头节点和尾节点控制栈顶和栈底。

3.2 链栈的基本操作

3.2.1 初始化栈

typedef struct Node {
    int data;
    struct Node *next;
} Node;
typedef struct {
    Node *head;
    Node *tail;
} LinkStack;
void InitStack(LinkStack *s) {
    s->head = s->tail = (Node *)malloc(sizeof(Node));
    if (!s->head) {
        exit(1);
    }
    s->head->next = NULL;
}

3.2.2 入栈

void Push(LinkStack *s, int x) {
    Node *p = (Node *)malloc(sizeof(Node));
    if (!p) {
        exit(1);
    }
    p->data = x;
    p->next = s->tail->next;
    s->tail->next = p;
    s->tail = p;
}

3.2.3 出栈

int Pop(LinkStack *s) {
    if (s->head == s->tail) {
        printf("栈空!\n");
        return 0;
    }
    Node *p = s->head->next;
    int x = p->data;
    s->head->next = p->next;
    if (s->head->next == NULL) {
        s->tail = s->head;
    }
    free(p);
    return x;
}

3.2.4 获取栈顶元素

int GetTop(LinkStack *s) {
    if (s->head == s->tail) {
        printf("栈空!\n");
        return 0;
    }
    return s->head->next->data;
}

第四章:实战笔记

4.1 求逆字符串

使用栈结构,将字符串中的字符依次入栈,然后出栈,即可得到逆序字符串。

#include <stdio.h>
#include <string.h>

void ReverseString(char *str) {
    SeqStack s;
    InitStack(&s);
    int len = strlen(str);
    for (int i = 0; i < len; ++i) {
        Push(&s, str[i]);
    }
    while (!IsStackEmpty(&s)) {
        printf("%c", Pop(&s));
    }
    printf("\n");
}

int main() {
    char str[] = "Hello, World!";
    ReverseString(str);
    return 0;
}

4.2 函数调用栈

在程序执行过程中,函数调用栈记录了函数的调用顺序。掌握栈操作可以帮助我们更好地理解程序运行过程。

总结

本文详细介绍了C语言中的栈操作,包括顺序栈和链栈的实现方法,以及栈在实际应用中的实战案例。通过学习本文,读者可以轻松驾驭栈这一数据结构,提高编程能力。