栈的基本操作:入栈,出栈,取栈顶元素
栈的特点是先进后出,本次以顺序栈和链式栈的方法来写栈的基本操作。
顺序栈
stack.h
#include<stdio.h>
#pragma once
#define StackMAX 1000
typedef char SeqListType;
typedef struct SeqListStack{
SeqListType data[StackMAX];
size_t size;
}SeqListStack;
void StackInit(SeqListStack* stack);//初始化
void StackDestroy(SeqListStack* stack);//销毁栈
void StackPush(SeqListStack* stack,SeqListType value);//入栈
void StackPop(SeqListStack* stack);//出栈
int StackTop(SeqListStack* stack,SeqListType* value);//取栈顶元素
stack.c
#define _CRT_SECURE_NO_WARNINGS 1
#include "stack.h"
void StackInit(SeqListStack* stack)
{
if (stack == NULL){
//非法输入
return;
}
stack->size = 0;
}
void StackDestroy(SeqListStack* stack)
{
if (stack == NULL){
//非法输入
return;
}
stack->size = 0;
}
void StackPush(SeqListStack* stack, SeqListType value)
{
if (stack == NULL){
return;
}
if (stack->size >= StackMAX){
return;
}
stack->data[stack->size++] = value;//尾插的方式入栈
return;
}
void StackPop(SeqListStack* stack)
{
if (stack == NULL){
//非法输入
return;
}
if (stack->size == 0){
return;
}
--stack->size;//尾删的方式出栈
}
int StackTop(SeqListStack* stack,SeqListType* value)
{
if (stack == NULL||value==NULL){
//非法输入
return 0;
}
if (stack->size == 0){
//空栈,返回0表示取栈顶元素失败
return 0;
}
*value = stack->data[stack->size - 1];
return 1;
}
////////////////////////////////////////////////////测试代码//////////////////////////////////////////////////////////////////
#define TestHeader printf("\n============================%s======================\n",__FUNCTION__)
void StackPrint(SeqListStack* stack,const char* msg){
if (stack == NULL){
return;
}
printf("[%s]\n", msg);
printf("[栈底]");
size_t i = 0;
for (; i < stack->size; i++){
printf("[%c]", stack->data[i]);
}
printf("[栈顶]\n");
return;
}
void TestInit(){
TestHeader;
SeqListStack stack;
StackInit(&stack);
StackPrint(&stack, "对栈进行初始化");
}
void TestDestroy(){
TestHeader;
SeqListStack stack;
StackDestroy(&stack);
StackPrint(&stack, "对栈进行销毁");
}
void TestPush(){
TestHeader;
SeqListStack stack;
StackInit(&stack);
StackPush(&stack, 'a');
StackPush(&stack, 'b');
StackPush(&stack, 'c');
StackPush(&stack, 'd');
StackPrint(&stack, "进栈四个元素");
}
void TestPop(){
TestHeader;
SeqListStack stack;
StackInit(&stack);
StackPush(&stack, 'a');
StackPush(&stack, 'b');
StackPush(&stack, 'c');
StackPush(&stack, 'd');
StackPrint(&stack, "进栈四个元素");
StackPop(&stack);
StackPop(&stack);
StackPrint(&stack, "出栈两个元素");
}
void TestTop(){
TestHeader;
SeqListStack stack;
StackInit(&stack);
StackPush(&stack, 'a');
StackPush(&stack, 'b');
StackPush(&stack, 'c');
StackPush(&stack, 'd');
StackPrint(&stack, "进栈四个元素");
char value;
int ret=StackTop(&stack, &value);
printf("expect d,actual %c\n", value);
printf("expect 1,actual %d\n", ret);
}
////////////////////////////////////////////////////main代码//////////////////////////////////////////////////////////////////
int main(){
TestInit();
TestDestroy();
TestPush();
TestPop();
TestTop();
return 0;
}
链式栈
LinkStack.h
#pragma once
#include<stdio.h>
#include<stddef.h>
#include<stdlib.h>
typedef char LinkType;
#define MaxSize 1000
typedef struct LinkNode{
LinkType data;
struct LinkNode* next;
}LinkNode;//栈节点结构体
typedef struct LinkStack{
LinkNode head;
}LinkStack;//栈结构体
LinkNode* LinkStackCreat(LinkType value);//创建新节点
void LinkStackInit(LinkStack* stack);//顺序栈的初始化
void LinkStackDestroy(LinkStack* stack);//销毁栈
void LinkStackPush(LinkStack* stack, LinkType value);//入栈
void LinkStackPop(LinkStack* stack);//出栈
int LinkStackTop(LinkStack* stack, LinkType value);//取栈顶元素
LinkStack.c
#include"LinkStack.h"
void LinkStackInit(LinkStack* stack){
if (stack == NULL){
//非法输入
return;
}
stack->head.data = 0;
stack->head.next = NULL;
}
LinkNode* LinkStackCreat(LinkType value)
{
LinkNode* new_node = (LinkNode*)malloc(sizeof(LinkNode));
new_node->data = value;
new_node->next = NULL;
return new_node;
}
void LinkStackPush(LinkStack* stack, LinkType value)
{
if (stack == NULL){
//非法输入
return;
}
LinkNode* cur = LinkStackCreat(value);
cur->next = stack->head.next;
stack->head.next = cur;//以头插的方式入栈
}
void LinkStackPop(LinkStack* stack)
{
if (stack == NULL){
//非法输入
return;
}
LinkNode* to_delete = stack->head.next;
stack->head.next = to_delete->next;
free(to_delete);//以头删的方式出栈
}
int LinkStackTop(LinkStack* stack, LinkType *value)
{
if (stack == NULL){
//非法输入
return 0;
}
*value = stack->head.next->data;
return 1;
}
void LinkStackDestroy(LinkStack* stack)
{
while (stack->head.next != NULL){
LinkStackPop(stack);
}
}
//////////////////////////////////////////测试代码//////////////////////////////////////////
#define TestHeader printf("\n===============%s=====================\n",__FUNCTION__)
void LinkStackPrint(LinkStack* stack, const char* msg){
if(stack==NULL){
printf("stack==NULL\n");
return;
}
printf("[%s]\n",msg);
printf("[栈顶]");
LinkNode* cur=stack->head.next;
for(;cur!=NULL;cur=cur->next){
printf("[%c]",cur->data);
}
printf("[栈底]\n");
}
void TestInit(){
TestHeader;
LinkStack stack;
LinkStackInit(&stack);
LinkStackPrint(&stack,"对栈进行初始化");
}
void TestPush(){
TestHeader;
LinkStack stack;
LinkStackInit(&stack);
LinkStackPush(&stack, 'a');
LinkStackPush(&stack, 'b');
LinkStackPush(&stack, 'c');
LinkStackPush(&stack, 'd');
LinkStackPrint(&stack, "入栈四个元素");
}
void TestPop(){
TestHeader;
LinkStack stack;
LinkStackInit(&stack);
LinkStackPush(&stack, 'a');
LinkStackPush(&stack, 'b');
LinkStackPush(&stack, 'c');
LinkStackPush(&stack, 'd');
LinkStackPrint(&stack, "入栈四个元素");
LinkStackPop(&stack);
LinkStackPop(&stack);
LinkStackPrint(&stack, "出栈两个元素");
}
void TestTop(){
TestHeader;
LinkStack stack;
LinkStackInit(&stack);
LinkStackPush(&stack, 'a');
LinkStackPush(&stack, 'b');
LinkStackPush(&stack, 'c');
LinkStackPush(&stack, 'd');
LinkStackPrint(&stack, "入栈四个元素");
char tmp;
int ret = LinkStackTop(&stack, &tmp);
printf("expect 1,actual %d\n", ret);
printf("expect d,actual %c\n", tmp);
}
void TestDestroy(){
TestHeader;
LinkStack stack;
LinkStackInit(&stack);
LinkStackPush(&stack, 'a');
LinkStackPush(&stack, 'b');
LinkStackPush(&stack, 'c');
LinkStackPush(&stack, 'd');
LinkStackPrint(&stack, "入栈四个元素");
LinkStackDestroy(&stack);
LinkStackPrint(&stack, "销毁栈");
}
在main函数中分别调用测试函数
int main(){
TestInit();
TestPush();
TestPop();
TestTop();
TestDestroy();
return 0;
}