首先,使用C++做开发的话,STL中是有栈可以直接使用的,但是用c语言的话就需要自己造“轮子”
为了简单说明栈的特性以及使用情景,我搬了一道LeetCode算法题过来:
算法-20.有效的括号
给定一个只包括 '(',')','{','}','[',']' 的字符串,判断字符串是否有效。
有效字符串需满足:
左括号必须用相同类型的右括号闭合。
左括号必须以正确的顺序闭合。
注意空字符串可被认为是有效字符串。
示例 1:
输入: "()"
输出: true
示例 2:
输入: "()[]{}"
输出: true
示例 3:
输入: "(]"
输出: false
示例 4:
输入: "([)]"
输出: false
示例 5:
输入: "{[]}"
输出: true
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/valid-parentheses
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
那么解题思路是什么样的呢:
1.初始化栈 S。
2.一次处理表达式的每个括号。
3.如果遇到开括号,我们只需将其推到栈上即可。这意味着我们将稍后处理它。
4.如果我们遇到一个闭括号,那么我们检查栈顶的元素。如果栈顶的元素是一个 相同类型的 左括号,那么我们将它从栈中弹出并 继续处理。否则,这意味着表达式无效。
5.如果到最后我们剩下的栈中仍然有元素,那么这意味着表达式无效。
作者:LeetCode
链接:https://leetcode-cn.com/problems/valid-parentheses/solution/you-xiao-de-gua-hao-by-leetcode/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
接下来就是本篇重点,想要自己实现一个栈,那么要包括两个方面:1.数据结构 2.基本接口
我使用数组作为底层结构来实现栈,操作接口,就是最简单的压栈弹栈和检查空、满
上代码:
mystack.h
#include <stdlib.h>
#include <stdio.h>
#include <stdbool.h>
/*
LEON:
类似于队列,ring和栈这样的数据结构,需要按顺序存储,不存在插入数据,适合用数组来实现
*/
typedef unsigned short stack_ptr_t;
typedef unsigned short stack_size_t;
typedef struct mystack {
volatile stack_ptr_t bottom;
volatile stack_ptr_t top;
const stack_size_t size;
unsigned char * const data;
} stack_t;
#define DECLARE_STACK(name, size) \
stack_t name = {0,0,size,(unsigned char* const)malloc(size*sizeof(unsigned char))};
/*压栈*/
extern bool StackPush(stack_t * pstack,unsigned char* data);
/*弹栈*/
extern bool StackPop(stack_t * pstack, unsigned char* data);
/*已有数据长度*/
extern int StackCount(stack_t * pstack);
/*清空栈*/
extern void ClearStack(stack_t * pstack);
实现接口,mystack.c
#include "mystack.h"
/*压栈*/
extern bool StackPush(stack_t * pstack, unsigned char* data) {
if (pstack->top == pstack->size )
return false;
pstack->data[pstack->top] = *data;
pstack->top++;
return true;
}
/*弹栈*/
extern bool StackPop(stack_t * pstack, unsigned char* data) {
if (pstack->top == pstack->bottom)
return false;
*data = pstack->data[pstack->top -1];
pstack->top--;
return true;
}
/*已有数据长度*/
extern int StackCount(stack_t * pstack) {
return pstack->top - pstack->bottom;
}
/*清空栈*/
extern void ClearStack(stack_t * pstack) {
pstack->top = pstack->bottom;
}
接下来用我们自己实现的栈来完成本篇已开始所提出的算法,看看好不好用
bool LeetCodeLocal::isValid(unsigned char * s) {
if (strlen((char const *)s) == 0)
return true;
if (strlen((char const *)s) == 1)
return false;
DECLARE_STACK(my_stack, 100);
int i = 0;
unsigned char out_char = 0;
while (i < strlen((char const *)s)) {
if ((s[i] == '(') || (s[i] == '[') || (s[i] == '{')) {
StackPush(&my_stack, &s[i]);
i++;
continue;
}
StackPop(&my_stack, &out_char);
if ((out_char == s[i] - 1) || (out_char == s[i] - 2)) {
i++;
continue;
}
return false;
}
if (StackCount(&my_stack))
return false;
return true;
}
main.cpp(虽然自己设计的栈是用c写的,但是测试用例还是习惯用c++来写,所以你也看到我之前写的接口都是有“extern”的
就是为了在c++工程中可以引用c实现的接口)
int main()
{
#if STACK_TEST
/*应用->有效括号*/
unsigned char s_0[] = "()";
unsigned char s_1[] = "(]";
unsigned char s_2[] = "({[]})";
LeetCodeLocal toolAPI;
cout << boolalpha << toolAPI.isValid(s_0) << endl;
cout << boolalpha << toolAPI.isValid(s_1) << endl;
cout << boolalpha << toolAPI.isValid(s_2);
#endif
system("pause");
return 0;
}
最后看下结果: