数据结构之栈的基本操作

栈的定义

  在计算机领域,栈是一种按序排列的数据结构,只能在一端(称为栈顶(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

测试结果:

描述
描述
描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值