1.3 栈
栈是一种 先进后出 的数据结构。栈是限定仅在表尾进行插入和删除操作的线性表
栈的读结点数据
读结点数据也就是读取栈结构中结点的数据。由于栈结构只能在一段进行操作,因此这里的读操作其实就是读栈顶的数据。
需要注意的是,读结点数据的操作和出栈不同。读结点数据的操作仅是显示栈顶结点数据的内容,而出栈操作则将栈顶数据弹出,该数据将不再存在。
下面是使用栈结构实现学生数据操作的代码(结构体实现):
#include<iostream>
using namespace std;
#include<string>
#define MAXLEN 50
//栈中存放的数据类型
struct DATA
{
char name[10];
int age;
};
//栈结构体
struct Stack
{
DATA data[MAXLEN]; //数据元素
int top; //栈顶
};
//栈的初始化
Stack *STInit() //由于函数返回的是一个指针,所以要用一个*来接收它
{
Stack *p;
if (p = (Stack *)malloc(sizeof(Stack))) //申请栈内存,如果申请成功,执行if里面的语句,否则返 回NULL
{
p->top = 0; //设置栈顶为0
return p; //返回指向栈的指针
}
return NULL;
}
int STISEmpty(Stack *s) //判断栈是否为空
{
int t;
t = (s->top == 0); //s 是结构体的指针,指向top域,如果是==0,则t是true、、、、否则t是false
return t;
}
int STIsFull(Stack *s) //判断栈是否已满
{
int t;
t = (s->top == MAXLEN);
return t;
}
void STClear(Stack *s) //清空栈
{
s->top = 0;
}
void STFree(Stack *s) //释放栈所用空间
{
if (s)
{
free(s);
}
}
//入栈操作的具体步骤:
//1.首先判断栈顶top。如果top大于或等于MAXLEN,则表示溢出,进行出错处理
//2.设置top=top+1(栈顶指针+1,指向入栈地址)
//3.将入栈元素保存到top指向的位置
int PushST(Stack *s, DATA data) //入栈操作
{
if ((s->top + 1) > MAXLEN)
{
cout << "栈溢出!" << endl;
return 0;
}
//将元素入栈
s->data[++s->top] = data; //等价于 s->top++; s->data[s->top]=data;先让栈顶指针+1,再将新 插入元素赋给栈顶空间
return 1;
}
//出栈步骤:
//1.首先判断栈顶top,如果top等于0,则表示为空栈,进行出错处理。
//2.将栈顶指针 top所指位置的元素返回。
//3.设置top=top-1,也就是是栈顶指针减1,指向栈的下一个元素,原来栈顶元素被弹出
//这里输入参数s为一个指向操作的栈的指针。该函数返回值是一个DATA类型的数据,返回值是栈顶的数据元素。
DATA PopST(Stack *s) //出栈操作
{
if (s->top == 0)
{
cout << "栈为空!" << endl;
exit(0);
}
return (s->data[s->top--]); //等价于 s->data[s->top]; s->top--;
}
DATA PeekST(Stack *s) //读栈顶数据
{
if (s->top == 0)
{
cout << "栈为空!" << endl;
exit(0);
}
return s->data[s->top];
}
int main()
{
Stack *stack;
DATA data, data1;
stack = STInit();
cout << "入栈操作:" << endl;
cout << "输入姓名 年龄进行入栈操作:";
do
{
cin >> data.name >> data.age;
//strcmp(a, b)这是一个字符串比较函数,
//如果a的字符串内容与b的字符串内容相同的话,返回0,即strcmp == 0
if (strcmp(data.name, "0") == 0)
{
break;
}
else
{
PushST(stack, data);
}
} while (1);
do
{
cout << endl << "出栈操作:按任意键进行出栈操作:";
getchar();
data1 = PopST(stack);
cout << "出栈的数据是:(" << data1.name <<" "<< data1.age << ")" << endl;
} while (1);
STFree(stack);
system("pause");
return 0;
}
程序运行结果如下:
使用C++的面向对象方式编写的栈数据结构实现代码:
#include<iostream>
using namespace std;
#define MAXSIZE 5
class Stack
{
public:
Stack()
{
m_top = -1;
}
//判断是否为空
int STIsEmpty()
{
return m_top == -1;
}
//判断栈是否已满
int STIsFull()
{
return m_top == MAXSIZE -1;
}
//清空栈
void STClear()
{
m_top = -1; //将栈顶置为-1表示栈中已经没有数据了
}
//判断栈的长度
int STLength()
{
return m_top + 1;
}
//入栈操作
void PushST(int value)
{
if (this->STIsFull())
{
cout << "栈溢出!" << endl;
return;
}
//先让栈顶向上移动一位,再将数据放入栈中
m_top++;
m_array[m_top] = value;
}
//出栈操作
int PopST()
{
if (this->STIsEmpty())
{
cout << "栈为空!" << endl;
exit(0);
}
//出栈时先将栈顶元素返回,再将栈顶向下移动一位
int result = m_array[m_top];
m_top--;
return result;
}
//读取栈顶元素
int getST()
{
if (this->m_top == -1)
{
cout << "栈为空!" << endl;
exit(0);
}
return m_array[m_top];
}
private:
int m_array[MAXSIZE]; //存放栈中数据的容器->数组
int m_top; //栈顶
};
int main()
{
Stack stack;
//判断栈是否为空
cout << stack.STIsEmpty() << endl;
//判断栈是否已满
cout << stack.STIsFull() << endl;
//入栈
stack.PushST(10);
stack.PushST(12);
cout << stack.getST() << endl; //读取栈顶元素
stack.PushST(15);
stack.PushST(18);
stack.PushST(20);
cout << stack.STLength() << endl; //判断栈的长度
cout << stack.STIsFull() << endl;
//读取栈顶元素
cout << stack.getST() << endl;
//出栈
//这里循环条件如果写为 i< stack.STLength()的话,只能输出三个数据
//stack.STLength()不是一个常数值,因为在执行出栈操作的时候,会执行m_top--,所以长度也会相应地变短
//所以这里改为5
for (int i = 0; i < 5; i++)
{
cout << stack.PopST() << endl;
}
system("pause");
return 0;
}
程序运行结果如下:
1
0
12
5
1
20
出栈:
20
18
15
12
10