栈的定义
在计算机领域,栈是一种按序排列的数据结构,只能在一端(称为栈顶(top))对数据项进行插入和删除。在单片机应用中,栈是个特殊的存储区,主要功能是暂时存放数据和地址,通常用来保护断点和现场。
栈与堆的区别:
1.空间分配
- 栈(操作系统):由操作系统自动分配释放 ,存放函数的参数值,局部变量的值等。
- 堆(操作系统):一般由程序员自己分配释放, 若程序员不释放,程序结束时可能由系统回收。
2.数据结构区别
- 栈(数据结构):一种先进后出的数据结构。
- 堆(数据结构):堆可以被看成是一棵树,如:堆排序。
顺序栈基本操作
①seqstack.h
#pragma once
#include <stddef.h>
typedef char SeqStackType;
#define SEQ_STACK_SIZE 100
typedef struct SeqStack{
SeqStackType data[SEQ_STACK_SIZE];
size_t size;
}SeqStack;
void SeqStackInit(SeqStack* stack); //初始化
void SeqStackDestroy(SeqStack* stack); //销毁栈
void SeqStackPush(SeqStack* stack, SeqStackType value); //入栈
void SeqStackPop(SeqStack* stack); //出栈
int SeqStackTop(SeqStack* stack, SeqStackType* value); //取栈顶元素
②seqstack.c
#include "seqstack.h"
//初始化
void SeqStackInit(SeqStack* stack){
if(stack == NULL){
return; //非法输入
}
stack->size = 0;
}
//销毁栈
void SeqStackDestroy(SeqStack* stack){
if(stack == NULL){
return; //非法输入
}
stack->size = 0;
}
//入栈
void SeqStackPush(SeqStack* stack, SeqStackType value){
if(stack == NULL){
return; //非法输入
}
if(stack->size >= SEQ_STACK_SIZE){
return; //栈已满
}
stack->data[stack->size++] = value;
}
//出栈
void SeqStackPop(SeqStack* stack){
if(stack == NULL){
return; //非法输入
}
if(stack->size == 0){
return; //空栈
}
--stack->size;
}
//取栈顶元素
int SeqStackTop(SeqStack* stack, SeqStackType* value){
if(stack == NULL || value == NULL){
return 0; //非法输入
}
if(stack->size == 0){
return 0; //空栈
}
*value = stack->data[stack->size - 1];
return 1;
}
//以下是测试函数
#if 1
#include <stdio.h>
#define TEST_HEADER printf("\n=============================%s=======================\n",__FUNCTION__)
void SeqStackPrintChar(SeqStack* stack, const char* msg){
if(stack == NULL){
printf("stack = NULL\n");
}
printf("[%s]:\n",msg);
printf("[栈底] ");
size_t i = 0;
for(; i < stack->size; ++i){
printf("[%c] ", stack->data[i]);
}
printf("[栈顶]\n");
}
void TestInit(){
TEST_HEADER;
SeqStack stack;
SeqStackInit(&stack);
SeqStackPrintChar(&stack, "初始化空栈");
printf("stack->size expect 0, actual %lu\n",stack.size);
}
void TestDestroy(){
TEST_HEADER;
SeqStack stack;
SeqStackInit(&stack);
SeqStackPush(&stack, 'a');
SeqStackPush(&stack, 'b');
SeqStackPush(&stack, 'c');
SeqStackPush(&stack, 'd');
SeqStackPrintChar(&stack, "入栈四个元素");
SeqStackDestroy(&stack);
SeqStackPrintChar(&stack, "销毁栈");
}
void TestPush(){
TEST_HEADER;
SeqStack stack;
SeqStackInit(&stack);
SeqStackPush(&stack, 'a');
SeqStackPush(&stack, 'b');
SeqStackPush(&stack, 'c');
SeqStackPush(&stack, 'd');
SeqStackPrintChar(&stack, "入栈四个元素");
}
void TestPop(){
TEST_HEADER;
SeqStack stack;
SeqStackInit(&stack);
SeqStackPush(&stack, 'a');
SeqStackPush(&stack, 'b');
SeqStackPush(&stack, 'c');
SeqStackPush(&stack, 'd');
SeqStackPrintChar(&stack, "入栈四个元素");
SeqStackPop(&stack);
SeqStackPrintChar(&stack, "出栈一个元素");
SeqStackPop(&stack);
SeqStackPrintChar(&stack, "再出栈一个元素");
SeqStackPop(&stack);
SeqStackPop(&stack);
SeqStackPrintChar(&stack, "再出栈两个元素");
SeqStackPop(&stack);
SeqStackPrintChar(&stack, "尝试对空栈出栈");
}
void TestTop(){
TEST_HEADER;
SeqStack stack;
SeqStackInit(&stack);
SeqStackPush(&stack, 'a');
SeqStackPush(&stack, 'b');
SeqStackPush(&stack, 'c');
SeqStackPush(&stack, 'd');
SeqStackPrintChar(&stack, "入栈四个元素");
char tmp = '\0';
int ret = SeqStackTop(&stack, &tmp);
printf("ret expect 1, actual %d\n",ret);
printf("tmp expect d, actual %c\n",tmp);
}
int main(){
TestInit();
TestDestroy();
TestPush();
TestPop();
TestTop();
return 0;
}
#endif
测试结果:
链式栈基本操作
①linkstack.h
#pragma once
#include <stddef.h>
typedef char LinkStackType;
typedef struct LinkStackNode{
LinkStackType data;
struct LinkStackNode* next;
}LinkStackNode;
//bottom为栈底指针
void LinkStackInit(LinkStackNode** bottom); //初始化栈
void LinkStackDestroy(LinkStackNode** bottom); //销毁栈
void LinkStackPush(LinkStackNode** bottom, LinkStackType value); //入栈
void LinkStackPop(LinkStackNode** bottom); //出栈
int LinkStackTop(LinkStackNode** bottom, LinkStackType* value); //取栈顶元素
②linkstack.c
#include "linkstack.h"
#include <stdio.h>
#include <stdlib.h>
LinkStackNode* CreateLinkStackNode(LinkStackType value){
LinkStackNode* ptr = (LinkStackNode*)malloc(sizeof(LinkStackNode));
ptr->data = value;
ptr->next = NULL;
return ptr;
}
void DestroyLinkStackNode(LinkStackNode* ptr){
free(ptr);
}
//初始化栈
void LinkStackInit(LinkStackNode** bottom){
if(bottom == NULL){
return; //非法输入
}
*bottom = NULL;
}
//销毁栈
void LinkStackDestroy(LinkStackNode** bottom){
if(bottom == NULL){
return; //非法输入
}
if(*bottom == NULL){
return; //空栈
}
LinkStackNode* cur = *bottom;
while(cur != NULL){
LinkStackNode* next = cur->next;
DestroyLinkStackNode(cur);
cur = next;
}
*bottom = NULL;
return;
}
//入栈
void LinkStackPush(LinkStackNode** bottom, LinkStackType value){
if(bottom == NULL){
return; //非法输入
}
if(*bottom == NULL){
//空栈
*bottom = CreateLinkStackNode(value);
return;
}
LinkStackNode* cur = *bottom;
while(cur->next != NULL){
cur = cur->next;
}
cur->next = CreateLinkStackNode(value);
return;
}
//出栈
void LinkStackPop(LinkStackNode** bottom){
if(bottom == NULL){
return; //非法输入
}
if(*bottom == NULL){
return; //空栈,出栈失败
}
LinkStackNode* cur = *bottom;
if(cur->next == NULL){ //栈中只有一个元素
DestroyLinkStackNode(cur);
*bottom = NULL;
return;
}
while(cur->next != NULL){
if(cur->next->next == NULL){
LinkStackNode* to_delete = cur->next;
cur->next = NULL;
DestroyLinkStackNode(to_delete);
}
else{
cur = cur->next;
}
}
return;
}
//取栈顶元素
int LinkStackTop(LinkStackNode** bottom, LinkStackType* value){
if(bottom == NULL){
return 0; //非法输入
}
if(*bottom == NULL){
return 0; //空栈,取栈顶元素失败
}
LinkStackNode* cur = *bottom;
if(cur->next == NULL){
*value = cur->data;
return 1;
}
while(cur->next != NULL){
cur = cur->next;
}
*value = cur->data;
return 1;
}
/////////////////////////////////////////////////////////////
//以下是测试函数
/////////////////////////////////////////////////////////////
#if 1
#define TEST_HEADER printf("\n===================================%s===================================\n",__FUNCTION__)
void LinkStackPrintChar(LinkStackNode* bottom, const char* msg){
printf("[%s]:\n",msg);
if(bottom == NULL){
printf("bottom = NULL\n");
}
printf("[栈底]");
LinkStackNode* cur = bottom;
for(;cur != NULL; cur = cur->next){
printf("[%c] ",cur->data);
}
printf("[栈顶]\n\n");
}
void TestInit(){
TEST_HEADER;
LinkStackNode* bottom;
LinkStackInit(&bottom);
LinkStackPrintChar(bottom,"初始化空栈");
}
void TestDestroy(){
TEST_HEADER;
LinkStackNode* bottom;
LinkStackInit(&bottom);
LinkStackPush(&bottom, 'a');
LinkStackPush(&bottom, 'b');
LinkStackPush(&bottom, 'c');
LinkStackPush(&bottom, 'd');
LinkStackPrintChar(bottom,"入栈四个元素");
LinkStackDestroy(&bottom);
LinkStackPrintChar(bottom,"销毁栈");
printf("bottom expect NULL, actual %p\n",bottom);
}
void TestPush(){
TEST_HEADER;
LinkStackNode* bottom;
LinkStackInit(&bottom);
LinkStackPush(&bottom, 'a');
LinkStackPush(&bottom, 'b');
LinkStackPush(&bottom, 'c');
LinkStackPush(&bottom, 'd');
LinkStackPrintChar(bottom,"入栈四个元素");
}
void TestPop(){
TEST_HEADER;
LinkStackNode* bottom;
LinkStackInit(&bottom);
LinkStackPush(&bottom, 'a');
LinkStackPush(&bottom, 'b');
LinkStackPush(&bottom, 'c');
LinkStackPush(&bottom, 'd');
LinkStackPrintChar(bottom,"入栈四个元素");
LinkStackPop(&bottom);
LinkStackPrintChar(bottom,"出栈一个元素");
LinkStackPop(&bottom);
LinkStackPrintChar(bottom,"再出栈一个元素");
LinkStackPop(&bottom);
LinkStackPop(&bottom);
LinkStackPrintChar(bottom,"出栈两个元素");
LinkStackPop(&bottom);
LinkStackPrintChar(bottom,"尝试对空栈出栈");
}
void TestTop(){
TEST_HEADER;
LinkStackNode* bottom;
LinkStackInit(&bottom);
printf("[对空栈取栈顶元素]:\n");
char tmp = '\0';
int ret = LinkStackTop(&bottom,&tmp);
printf("ret expect 0, actual %d\n",ret);
printf("tmp expect , actual %c\n\n",tmp);
LinkStackPush(&bottom, 'a');
LinkStackPush(&bottom, 'b');
LinkStackPush(&bottom, 'c');
LinkStackPush(&bottom, 'd');
LinkStackPrintChar(bottom,"入栈四个元素");
printf("[取栈顶元素]:\n");
ret = LinkStackTop(&bottom,&tmp);
printf("ret expect 1, actual %d\n",ret);
printf("tmp expect d, actual %c\n",tmp);
}
int main(){
TestInit();
TestDestroy();
TestPush();
TestPop();
TestTop();
return 0;
}
#endif
测试结果: