数据结构与算法之栈
1.栈(Stack)的基本概念
栈是限制仅能在表的一端进行插入和删除操作的线性表。允许插入和删除的一端叫做栈顶,另一端则为栈底。其的特点是后进先出(Last in First Out)。
2.栈的存储结构
-
栈的顺序存储结构称为顺序栈。顺序栈是利用一组连续的存储单元依次存放元素,通常用一维数组存放栈的元素。同时设“指针”top指示栈顶元素的当前位置。(top不是指针变量,指示整型变量)。栈的顺序结构使用方便,但必须预先分配内存,可能造成存储空间浪费或栈溢出的缺点。
-
栈的链式存储结构称为链栈,其组织形式与单链表类似。链表尾部结点为栈底,头部结点为栈顶。栈顶由指针head唯一确定,栈底结点的next域为NULL。
3.栈运算
栈的常见操作有初始化(栈置空)、判断栈空、进栈、出栈、求栈深、读取栈顶元素等基本运算。 以下为基于c和c++的栈的实现:
以下为基于c++的顺序栈的实现:
Stack.h
#ifndef STACK_H
#define STACK_H
class Stack
{
public:
Stack(int size);//分配内存初始化占空间,设置栈容量、栈顶
~Stack();//回收占空间内存
bool stackEmpty();//判栈空
bool stackFull();//判栈满
void clearStack();//清空栈
int stackLength();//元素个数
bool push(char elem);//入栈
bool pop(char &elem);//出栈
void stackTraverse(bool isFromButtom);//遍历
private:
char *m_pBuffer; //栈空间指针
int m_iSize; //栈容量
int m_iTop; //栈顶指针,等于元素个数
};
#endif
Stack.cpp
#include<iostream>
#include<stdlib.h>
#include<string>
#include"Stack.h"
using namespace std;
//初始化
Stack::Stack(int size)
{
m_iSize = size;
m_pBuffer = new char[size];
m_iTop = 0;
}
//销毁
Stack::~Stack()
{
delete[]m_pBuffer;
m_pBuffer = NULL;
}
//判空
bool Stack::stackEmpty()
{
return m_iTop == 0 ? true : false;
}
//判满
bool Stack::stackFull()
{
return m_iTop == m_iSize ? true : false;
}
//清空栈
void Stack::clearStack()
{
m_iTop = 0;
}
//元素个数
int Stack::stackLength()
{
return m_iTop;
}
//入栈
bool Stack::push(char elem)
{
if (stackFull())
{
cout << "栈满!\n";
return false;
}
else
{
*(m_pBuffer + m_iTop) = elem;
m_iTop++;
return true;
}
}
//出栈
bool Stack::pop(char &elem)
{
if (stackEmpty())
{
cout << "栈为空!\n";
return false;
}
else
{
elem = *(m_pBuffer + m_iTop - 1);
m_iTop--;
return true;
}
}
//遍历
void Stack::stackTraverse(bool isFromButtom)
{
if (isFromButtom)
{
for (int i = 0; i < m_iTop; i++)//从栈底开始遍历
{
cout << *(m_pBuffer + i) << endl;
}
}
else
{
for (int i = m_iTop - 1; i >= 0; i--)//从栈顶开始遍历
{
cout << *(m_pBuffer + i) << endl;
}
}
}
main.cpp
#include<iostream>
#include<stdlib.h>
#include<string>
#include"Stack.h"
using namespace std;
int main(void)
{
Stack *p = new Stack(5);
/*p->push('h'); 测试
p->push('e');
p->push('l');
p->push('l');
p->push('o');
p->stackTraverse(true);
char elem = ' ';
p->pop(elem);
cout << elem << endl;
p->stackTraverse(true);
cout << p->stackLength() << endl;
p->clearStack();
cout << p->stackLength()<< endl;
if (p->stackEmpty())
{
cout << "空!\n";
}
if (p->stackFull())
{
cout << "满!\n";
}*/
delete p;
p = NULL;
system("pause");
return 0;
}
以下为基于c的顺序栈和链栈的实现:
顺序栈
//栈的顺序存储结构
#include<stdio.h>
#include<stdlib.h>
#define MAXSIZE 5 //宏定义,栈可能的最大元素数目
typedef int elemtype;
typedef struct //顺序栈类型说明
{
elemtype elem[MAXSIZE];
int top;
}sqstacktp;
int main(void)
{
void InitStack(sqstacktp *s);
int StackEmpty(sqstacktp *s);
void Push(sqstacktp *s, elemtype x);
elemtype Pop(sqstacktp *s);
int Size(sqstacktp *p);
sqstacktp *s;
s = (sqstacktp *)malloc(sizeof(sqstacktp));
InitStack(s);//栈置空
if (StackEmpty(s))//判断栈是否为空
printf("The stack is empty!\n");
else
{
printf("The stack is not empty!!!\n");
InitStack(s);
}
elemtype x;
while (s->top != MAXSIZE)
{
scanf_s("%d", &x);
Push(s, x);
}
while (!StackEmpty(s))
{
printf("%d\n", Pop(s));
}
return 0;
}
//初始化栈
void InitStack(sqstacktp *s)
{
//将顺序栈置为空
s->top = 0;
}
//判断栈是否为空
int StackEmpty(sqstacktp *s)
{
if (s->top > 0)
return 0;
else
return 1;
}
//进栈
void Push(sqstacktp *s, elemtype x)
{
if (s->top != MAXSIZE)
s->elem[s->top++] = x;
else
printf("Overflow!!!\n");
}
//出栈
elemtype Pop(sqstacktp *s)
{
if (s->top == 0)
return NULL;
else
{
s->top--;
return s->elem[s->top];
}
}
//栈深
int Size(sqstacktp *s)
{
return (s->top);
}
链栈
//栈的链式存储结构————链栈
#include<stdio.h>
#include<stdlib.h>
typedef int elemtype;
typedef struct stacknode //链栈的类型定义
{
elemtype data;
struct stacknode *next;
}stacknode;
typedef struct
{
stacknode *top; //栈顶指针
}LinkStack;
int main(void)
{
void InitStack(LinkStack *ls);
void Push(LinkStack *ls, elemtype x);
elemtype Pop(LinkStack *ls);
LinkStack *ls;
ls = (LinkStack *)malloc(sizeof(LinkStack));
InitStack(ls);
elemtype i = 0;
while (i != 5)
{
Push(ls, i);
i++;
}
while (ls->top != NULL)
printf("%d\n", Pop(ls));
return 0;
}
//初始化
void InitStack(LinkStack *ls)
{
//建立一个空栈
ls->top = NULL;
}
//进栈
void Push(LinkStack *ls, elemtype x)
{
stacknode *s = NULL;
s = (stacknode *)malloc(sizeof(stacknode));//生成新结点
s->data = x;
s->next = ls->top;//链入新结点
ls->top = s;//修改栈顶指针
}
//出栈
elemtype Pop(LinkStack *ls)
{
stacknode *p = NULL;
elemtype x;
if (ls->top == NULL)
return NULL;
else
{
x = (ls->top)->data;
p = ls->top;
ls->top = p->next;
free(p);
return x;//返回原栈顶元素值
}
}