1.栈的概念
2.栈的顺序存储
//seqStack.h
#pragma once
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <stddef.h>//可计算偏移量
#include <stdbool.h>
#ifdef __cplusplus
extern "C" {
#endif
#define MAX 1024
//顺序栈数据结构
struct SStack {
void* data[MAX];//存放数据的数组
int size;//栈中元素的个数
};
typedef void* seqStack;
//数组高下标的位置为栈顶,插入和删除不需要移动元素
//初始化
seqStack* init_seqStack();
//入栈
void push_seqStack(seqStack stack, void* data);
//出栈
void pop_seqStack(seqStack stack);
//获取栈顶元素
void* top_seqStack(seqStack stack);
//获得栈大小
int size_seqStack(seqStack stack);
//销毁栈
void destroy_seqStack(seqStack stack);
#ifdef __cplusplus
}
#endif
//seqStack.c
#include"seqStack.h"
//初始化
seqStack* init_seqStack() {
struct SStack* stack = malloc(sizeof(struct SStack));
if (NULL == stack)
return NULL;
memset(stack, 0, sizeof(struct SStack));
stack->size = 0;
return stack;
}
//入栈
void push_seqStack(seqStack stack, void* data) {
if (NULL == stack)
return;
if (NULL == data)
return;
struct SStack* s = (struct SStack*)stack;
s->data[s->size] = data;
s->size++;
}
//出栈
void pop_seqStack(seqStack stack) {
if (NULL == stack)
return;
struct SStack* s = (struct SStack*)stack;
if (s->size == 0)
return;
s->data[s->size - 1] = NULL;
s->size--;
}
//获取栈顶元素
void* top_seqStack(seqStack stack) {
if (NULL == stack)
return NULL;
struct SStack* s = (struct SStack*)stack;
if (s->size == 0)
return NULL;
return s->data[s->size - 1];
}
//获得栈大小
int size_seqStack(seqStack stack) {
if (NULL == stack)
return;
struct SStack* s = (struct SStack*)stack;
return s->size;
}
//销毁栈
void destroy_seqStack(seqStack stack) {
if (NULL == stack)
return;
struct SStack* s = (struct SStack*)stack;
free(stack);
stack = NULL;
}
//main.c
#include "seqStack.h"
struct Person {
char name[64];
int age;
};
void test() {
//初始化栈
seqStack stack = init_seqStack();
//创建数据
struct Person p1 = { "aaa",10 };
struct Person p2 = { "bbb",20 };
struct Person p3 = { "ccc",30 };
struct Person p4 = { "ddd",40 };
struct Person p5 = { "eee",50 };
struct Person p6 = { "fff",60 };
//入栈
push_seqStack(stack, &p1);
push_seqStack(stack, &p2);
push_seqStack(stack, &p3);
push_seqStack(stack, &p4);
push_seqStack(stack, &p5);
push_seqStack(stack, &p6);
//输出栈中所有元素
while (size_seqStack(stack) > 0) {
//获得栈顶元素
struct Person* person = (struct Person*)top_seqStack(stack);
//打印
printf("Name:%s Age:%d\n", person->name, person->age);
//弹出栈顶元素
pop_seqStack(stack);
}
printf("Size:%d\n", size_seqStack(stack));
//销毁栈
destroy_seqStack(stack);
stack = NULL;
}
int main() {
test();
return 0;
}
3.栈的链式存储
//linkStack.h
#pragma once
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <stddef.h>//可计算偏移量
#include <stdbool.h>
#ifdef __cplusplus
extern "C" {
#endif
struct stackNode {
struct stackNode* next;
};
struct LStack {
struct stackNode header;//头结点
int size;
};
typedef void* linkStack;
//初始化
linkStack init_linkStack();
//入栈
void push_linkStack(linkStack stack, void* data);
//出栈
void pop_linkStack(linkStack stack);
//获得栈顶元素
void* top_linkStack(linkStack stack);
//获得大小
int size_linkStack(linkStack stack);
//销毁栈
void destroy_linkStack(linkStack stack);
#ifdef __cplusplus
}
#endif
//linkStack.c
#include "linkStack.h"
//初始化
linkStack init_linkStack() {
struct LStack* stack = malloc(sizeof(struct LStack));
if (NULL == stack)
return NULL;
stack->header.next = NULL;
stack->size = 0;
return stack;
}
//入栈
void push_linkStack(linkStack stack, void* data) {
if (NULL == stack)
return;
if (NULL == data)
return;
struct LStack* ls = (struct LStack*)stack;
//data数据的前四个字节为指针,需要进行强转换拿到指针
struct stackNode* node = (struct stackNode*)data;
//插入链表
node->next = ls->header.next;
ls->header.next = node;
ls->size++;
}
//出栈
void pop_linkStack(linkStack stack) {
if (NULL == stack)
return;
struct LStack* ls = (struct LStack*)stack;
if (ls->size == 0)
return;
//缓存第一个节点
struct stackNode* pFirst = ls->header.next;
ls->header.next = pFirst->next;
ls->size--;
}
//获得栈顶元素
void* top_linkStack(linkStack stack) {
if (NULL == stack)
return NULL;
struct LStack* ls = (struct LStack*)stack;
if (ls->size == 0)
return NULL;
return ls->header.next;
}
//获得大小
int size_linkStack(linkStack stack) {
if (NULL == stack)
return -1;
struct LStack* ls = (struct LStack*)stack;
return ls->size;
}
//销毁栈
void destroy_linkStack(linkStack stack) {
if (NULL == stack)
return;
free(stack);
stack = NULL;
}
//main.c
#include "linkStack.h"
struct Person {
struct stackNode node;
char name[64];
int age;
};
void test() {
//初始化栈
linkStack stack = init_linkStack();
//创建数据
struct Person p1 = { NULL, "aaa",10 };
struct Person p2 = { NULL, "bbb",20 };
struct Person p3 = { NULL, "ccc",30 };
struct Person p4 = { NULL, "ddd",40 };
struct Person p5 = { NULL, "eee",50 };
struct Person p6 = { NULL, "fff",60 };
//入栈
push_linkStack(stack, &p1);
push_linkStack(stack, &p2);
push_linkStack(stack, &p3);
push_linkStack(stack, &p4);
push_linkStack(stack, &p5);
push_linkStack(stack, &p6);
//输出栈中所有元素
while (size_linkStack(stack) > 0) {
//获得栈顶元素
struct Person* person = (struct Person*)top_linkStack(stack);
//打印
printf("Name:%s Age:%d\n", person->name, person->age);
//弹出栈顶元素
pop_linkStack(stack);
}
printf("Size:%d\n", size_linkStack(stack));
//销毁栈
destroy_linkStack(stack);
stack = NULL;
}
int main() {
test();
return 0;
}
4.栈的应用—就近匹配
//seqStack.h为上面的栈的顺序存储实现
#include "seqStack.h"
int isLeft(char ch) {
return ch == '(';
}
int isRight(char ch) {
return ch == ')';
}
void printError(const char* str, char* errMsg, char *pos) {
printf("错误信息:%s\n", errMsg);
printf("%s\n", str);
int dis = pos - str;
for (int i = 0; i < dis; ++i) {
printf(" ");
}
printf("A\n");
}
void test() {
const char* str = "5+5*(6)+9/3*1)-(1+3(";
char* p = (char *)str;
//初始化栈
seqStack stack = init_seqStack();
while (*p != '\0') {
//判断当前字符是否为左括号
if (isLeft(*p))
push_seqStack(stack, p);
//判断当前字符是否为右括号
if (isRight(*p)) {
//当栈为空时,没有匹配的左括号
if (size_seqStack(stack) > 0)
pop_seqStack(stack);
else {
printError(str, "右括号没有匹配的左括号!", p);
}
}
p++;
}
while (size_seqStack(stack) > 0) {
printError(str, "没有匹配的右括号!", top_seqStack(stack));
//弹出栈顶
pop_seqStack(stack);
}
//销毁栈
destroy_seqStack(stack);
stack = NULL;
}
int main() {
test();
return 0;
}