关于栈的详细讲解我就不多说了,如果有不明白的移驾
本篇着重介绍的是使用顺序表实现的栈结构,话不多说
SeqStack.h
#pragma once
#include <stdlib.h>
#include <stddef.h>
#include <errno.h>
#define Datatype char
typedef struct SeqStack {
// 栈存放数据的总空间大小
Datatype* data;
// 当前栈长度
size_t size;
// 栈总长度,容量不够了进行扩容
size_t capacity;
} SeqStack;
// 栈初始化为空栈
void SeqStackInit(SeqStack* stack);
// 栈销毁
void SeqStackDestroy(SeqStack* stack);
// 入栈
void SeqStackPush(SeqStack* stack, Datatype value);
// 出栈
void SeqStackPop(SeqStack* stack);
// 取栈顶元素, 输出型参数value用来接收栈顶的值,函数返回值返回函数是否是执行成功
int SeqStackTop(SeqStack* stack, Datatype* value);
SeqStack.c
#include "SeqStack.h"
// 栈初始化为空栈
void SeqStackInit(SeqStack* stack) {
// 非法输入
if(stack == NULL) {
perror("SeqStackInit");
return;
}
stack->size = 0;
stack->capacity = 1000; // 默认栈大小为1000
stack->data = (Datatype*)malloc(sizeof(Datatype)*(stack->capacity));
}
// 栈销毁
void SeqStackDestroy(SeqStack* stack) {
// 非法输入
if(stack == NULL) {
perror("SeqStackDestroy");
return;
}
stack->size = 0;
stack->capacity = 0;
free(stack->data);
}
// 入栈, 采用尾插
// 扩容
void SeqStackResize(SeqStack* stack) {
// 非法输入
if(stack == NULL) {
perror("SeqStackResize");
return;
}
// 将原有的数据记录
Datatype* tmp = stack->data;
// 这里采用的扩容策略是原有data大小乘以2
stack->capacity *= 2;
stack->data = (Datatype*)malloc(sizeof(Datatype)*stack->capacity);
// 数据转移
int i = 0;
for( ; i < stack->size; i++) {
stack->data[i] = tmp[i];
}
// 销毁原有空间
free(tmp);
}
void SeqStackPush(SeqStack* stack, Datatype value) {
// 非法输入
if(stack == NULL) {
perror("SeqStackPop");
return;
}
// 栈内存已满,需要扩容
if(stack->size == stack->capacity) {
// 栈扩容
SeqStackResize(stack);
}
stack->data[stack->size++] = value;
}
// 出栈,尾删
void SeqStackPop(SeqStack* stack) {
// 非法输入
if(stack == NULL) {
perror("SeqStackPop");
return;
}
// 空栈
if(stack->size == 0) {
return;
}
stack->size--;
}
// 取栈顶元素
int SeqStackTop(SeqStack* stack, Datatype* value) {
// 非法输入
if(stack == NULL) {
perror("SeqStackTop");
return 0;
}
// 空栈
if(stack->size == 0) {
return 0;
}
*value = stack->data[stack->size-1];
return 1;
}
/* ************************************************
* ******************** test **********************
* ************************************************/
#if 1
#include <stdio.h>
#define FUNCTION() printf("\n================ %s ===============\n", __FUNCTION__)
// 打印栈
void print(SeqStack stack, const char* msg) {
printf("%s\n", msg);
int i = 0;
// 空栈
if(stack.size == 0) {
printf("空栈\n");
return ;
}
printf("栈底↓\n");
for( ; i < stack.size; i++) {
printf("%c\n", stack.data[i]);
}
printf("栈顶↑\n");
return;
}
// 初始化测试函数
void TestInit() {
FUNCTION();
SeqStack stack;
SeqStackInit(&stack);
print(stack, "初始化测试");
printf("size = %d, capacity = %d\n", stack.size, stack.capacity);
}
// 入栈测试
void TestPush() {
FUNCTION();
SeqStack stack;
SeqStackInit(&stack);
SeqStackPush(&stack, 'a');
SeqStackPush(&stack, 'b');
SeqStackPush(&stack, 'c');
SeqStackPush(&stack, 'd');
print(stack, "入栈a,b,c,d");
printf("except: size is 4, capacity is 1000\nactual: size is %d, capacity is %d\n ", stack.size, stack.capacity);
}
// 扩容测试
void TestResize() {
FUNCTION();
SeqStack stack;
SeqStackInit(&stack);
int i = 0;
for( ; i < 1001; i++) {
SeqStackPush(&stack, 'a');
}
printf("except: size is 1001, capacity is 2000\nactual: size is %d, capacity is %d\n ", stack.size, stack.capacity);
}
// 出栈测试
void TestPop() {
FUNCTION();
SeqStack stack;
SeqStackInit(&stack);
SeqStackPush(&stack, 'a');
SeqStackPush(&stack, 'b');
SeqStackPush(&stack, 'c');
SeqStackPush(&stack, 'd');
print(stack, "入栈a,b,c,d");
SeqStackPop(&stack);
SeqStackPop(&stack);
print(stack, "出栈两个");
SeqStackPop(&stack);
SeqStackPop(&stack);
print(stack, "出栈两个");
SeqStackPop(&stack);
print(stack, "对空栈出栈");
}
// 取栈顶元素测试
void TestTop() {
FUNCTION();
SeqStack stack;
SeqStackInit(&stack);
SeqStackPush(&stack, 'a');
SeqStackPush(&stack, 'b');
SeqStackPush(&stack, 'c');
SeqStackPush(&stack, 'd');
print(stack, "入栈a,b,c,d");
Datatype value = 0;
int ret = SeqStackTop(&stack, &value);
printf("ret = %d\n", ret);
printf("except: top is d \n actual:top is %c\n ", value);
}
int main() {
TestInit();
TestPush();
TestResize();
TestPop();
TestTop();
return 0;
}
#endif
本篇包含代码是现在CentOS6.5
如有错误,请斧正