栈是一种特殊的线性表,仅能在线性表的一端操作,栈顶允许操作,栈底不允许操作。
栈的特性:后进先出
栈的基本操作包括创建栈、销毁栈、出栈、入栈、获取栈顶元素、获取栈的大小、清空栈。
template <typename T>
class Stack:public Object
{
public:
virtual void push(const T& value) = 0;//入栈
virtual void pop() = 0;//出栈
virtual void clear() = 0;//清空栈
virtual T top()const = 0;//获取栈顶元素
virtual int size()const = 0;//获取栈的大小
};
栈可以使用顺序存储结构的内存空间实现,其内存空间分布如下:
根据存储空间的分配方式可以分为使用原生数组实现的静态栈和使用动态分配的堆空间实现的动态栈。
静态栈的实现要点如下:
A、类模板实现
B、使用原生数组作为栈的存储空间
C、使用模板参数决定栈的容量大小
静态栈的实现如下:
template<typename T, int N>
class StaticStack:public Stack<T>
{
protected:
T m_space[N];//栈存储空间
int m_top;//栈顶标识
int m_size;//当前栈的大小
public:
StaticStack()//构造函数初始化成员
{
m_top = -1;
m_size = 0;
}
int capacity()const//栈的容量
{
return N;
}
void push(const T& value)//压栈
{
if(m_size < N)
{
m_space[m_top + 1] = value;
m_size++;
m_top++;
}
else
{
THROW_EXCEPTION(InvalidOperationException, "No enough memory...");
}
}
void pop()//出栈
{
if(m_size > 0)
{
m_top--;
m_size--;
}
else
{
THROW_EXCEPTION(InvalidOperationException, "No element...");
}
}
T top() const//获取栈顶元素
{
if(m_size > 0)
{
return m_space[m_top];
}
else
{
THROW_EXCEPTION(InvalidOperationException, "No element...");
}
}
void clear()//清空栈
{
m_top = -1;
m_size = 0;
}
int size()const//当前栈的大小
{
return m_size;
}
};
静态栈的缺陷:
当存储的元素类型为类类型时,创建静态栈时会多次调用元素类型的类构造函数,影响效率。
栈使用链式存储结构实现的内容空间分布如下:
链式栈的实现要点:
A、类模板实现,继承自抽象父类Stack
B、内部组合使用LinkList类,实现栈的链式存储
C、只在单链表成员对象的头部进行操作
链式栈的实现:
template <typename T>
class LinkedStack:public LinkedList<T>
{
protected:
LinkedList<T> m_list;
public:
void push(const T& value)//压栈
{
m_list.insert(0, value);
}
void pop()//出栈
{
if(m_list.length() > 0)
{
m_list.remove(0);
}
else
{
THROW_EXCEPTION(InvalidOperationException, "No element...");
}
}
T top()const//获取栈顶元素
{
if(m_list.length() > 0)
{
return m_list.get(0);
}
else
{
THROW_EXCEPTION(InvalidOperationException, "No element...");
}
}
void clear()//清空栈
{
m_list.clear();
}
int size()const//获取栈大小
{
m_list.length();
}
};
栈具有先进后出的特性,适用于检测就近匹配的成对出现的符号。
符号匹配问题
从第一个字符开始扫描,遇到普通字符时忽略,遇到左符号时压入栈,遇到右符号时弹出栈顶元素进行匹配。如果匹配成功,所有字符扫描完毕并且栈为空;如果匹配失败,所有字符扫描完成但栈非空。
bool isLeft(char c)//左符号
{
return (c == '(') || (c == '[') || (c == '{') || (c == '<');
}
bool isRight(char c)//右符号
{
return (c == ')') || (c == ']') || (c == '}') || (c == '>');
}
bool isQuot(char c)//引号、双引号
{
return (c == '\'') || (c == '\"');
}
bool isMatch(char left, char right)//是否匹配
{
return ((left == '(')&&(right == ')')) ||
((left == '[')&&(right == ']')) ||
((left == '{')&&(right == '}')) ||
((left == '<')&&(right == '>')) ||
((left == '\'')&&(right == '\'')) ||
((left == '\"')&&(right == '\"'));
}
bool parse(const char* code)//解析字符串
{
LinkedStack<char> stack;
int i = 0;
bool ret = true;
code = (code == NULL)?"":code;
while(ret && (code[i] != '\0'))
{
if(isLeft(code[i]))//左符号
{
stack.push(code[i]);//压栈
}
else if(isRight(code[i]))//右符号
{
//当前字符是右符号,与栈顶元素匹配
if((stack.size() > 0) && isMatch(stack.top(), code[i]))
{
stack.pop();//弹出
}
else
{
ret = false;
}
}
else if(isQuot(code[i]))//引号、双引号
{
//栈为空或当前符号与栈顶元素不匹配
if((stack.size() == 0) || !isMatch(stack.top(), code[i]))
{
stack.push(code[i]);//压栈
}
//当前元素与栈顶元素匹配
else if(isMatch(stack.top(), code[i]))
{
stack.pop();//弹栈
}
}
i++;
}
return ret && (stack.size() == 0);
}
另外有需要云服务器可以了解下创新互联scvps.cn,海内外云服务器15元起步,三天无理由+7*72小时售后在线,公司持有idc许可证,提供“云服务器、裸金属服务器、高防服务器、香港服务器、美国服务器、虚拟主机、免备案服务器”等云主机租用服务以及企业上云的综合解决方案,具有“安全稳定、简单易用、服务可用性高、性价比高”等特点与优势,专为企业上云打造定制,能够满足用户丰富、多元化的应用场景需求。
分享文章:数据结构(八)——栈-创新互联
当前URL:/article38/doposp.html
成都网站建设公司_创新互联,为您提供移动网站建设、网站改版、响应式网站、微信公众号、云服务器、软件开发
声明:本网站发布的内容(图片、视频和文字)以用户投稿、用户转载内容为主,如果涉及侵权请尽快告知,我们将会在第一时间删除。文章观点不代表本网站立场,如需处理请联系客服。电话:028-86922220;邮箱:631063699@qq.com。内容未经允许不得转载,或转载时需注明来源: 创新互联