3-1 栈 及其 C++实现

3-1 栈

1、基本概念

栈是限制仅在表的一端进行插入和删除操作线性表

通常称插入、删除的这一端为 栈顶, 另一端称为栈底。当表中没有元素时称为空栈。

由于栈中元素的插入和删除操作都只能在栈顶进行,所以总是后进栈的先出栈。

(LIFO) Last In First Out. 后进先出

栈的基本操作有五种:

①init(),将栈S初始化为空

②empty() 判空栈,判断栈是否为空

③top() 取栈顶, 读取栈顶元素,但并不修改栈(top)

④pop() 出栈:若栈非空,则删除栈顶元素,(亦称 弹出 pop)

⑤push(x) 进栈:在栈顶插入元素,(亦称为 压入 push)

 

 

由于栈是运算受限的线性表,所以线性表的存储结构:顺序存储 和 链式存储 都对栈适用。

 

2、顺序栈

就是用顺序表来实现栈结构

①头文件:sq_stack.h

#ifndef SQ_STACK_H_
#define SQ_STACK_H_

#define MAX 10
struct sq_stack{
	int data[MAX];
	int top;
};


void Init(sq_stack * s);/*初始化*/
bool Empty(sq_stack * s);/*判断是否为空*/
int Top(sq_stack * s);/*返回栈顶元素的值*/
int Pop(sq_stack * s);/*返回栈顶元素,并将其从stack中删除*/
void Push(sq_stack * s, int x);/*将元素从栈顶放入栈中*/

#endif // !SQ_STACK_H_

②函数定义文件:sq_stack.cpp

#include<iostream>
#include"sq_stack.h"

using std::cin;
using std::cout;
using std::endl;


/*初始化*/
void Init(sq_stack * s) {
	s->top = -1;
}
/*判断是否为空*/
bool Empty(sq_stack * s) {
	if (s->top == -1)
		return true;
	else
		return false;
}

/*返回栈顶元素的值*/
int Top(sq_stack * s) {
	if (Empty(s))
		return NAN;
	else
		return s->data[s->top];
}

/*返回栈顶元素,并将其从stack中删除*/
int Pop(sq_stack * s) {
	if (Empty(s))
		return NAN;
	else
		return s->data[s->top--];//这里比Top函数里面只改变了一点,就是多了个自剑运算符
}

/*将元素从栈顶放入栈中*/
void Push(sq_stack * s, int x) {
	if (s->top == MAX - 1)//栈满
		return;
	else
		s->data[++s->top] = x;
}

③主函数文件:use.cpp

#include<iostream>
#include"sq_stack.h"

int main() {
	using namespace std;

	sq_stack s1;
	Init(&s1);

	if (Empty(&s1))
		cout << "\n stack is empty!" << endl;

	cout << "\n push_s ..." << endl;
	for (int i = 1; i < 100 ; i++) {//这里故意让i能取到99,但其实i=10的时候就已经满栈了
		Push(&s1, i);
	}

	cout << "\n pop_s ..." << endl;
	for (int i = 1; i < 100 && !Empty(&s1); i++) {
		cout << "\n top of stack: " << Top(&s1) << endl;
		Pop(&s1);
	}

3、链栈,

一般将链表头部作为栈顶,这样可以避免在 入栈 和 出栈的时候进行大量的遍历操作。

所以其实就是把单链表拿来用,只不过限制了插入和删除的位置而已。只能在首元素那里插、删

我这里借鉴的带头结点的链表,当然也可使用不带头结点的,

使用带头结点的单链表可以避免在首元素位置插入删除时修改头指针

 

 

①头文件 link_stack.h

#ifndef LINK_STACK_H_
#define LINK_STACK_H_


//链栈结点定义
typedef struct link_stack_node {
	int data;// 数据
	struct link_stack_node * next;//指向下一个元素的指针
}node;


//链栈定义
struct link_stack {
	node *top;//栈顶的指针
	int length;//链栈长度
};

void Init_Lstack(link_stack *s);
bool IsEmpty(link_stack *s);

void push_Ls(link_stack *s, int x);
int pop_Ls(link_stack *s);
int top_Ls(link_stack *s);
void Destroy(link_stack *s);


#endif // !LINK_STACK_H_

②函数定义文件: link_stack.cpp

#include<iostream>
#include"link_stack.h"
using std::cin;
using std::cout;
using std::endl;

void Init_Lstack(link_stack *s) {

	s->top = new node;
	s->top->next = nullptr;
	s->length = 0;
}

bool IsEmpty(link_stack *s) {
	if (s->top->next == nullptr)
		return true;
	else
		return false;
}

int top_Ls(link_stack *s) {
	if (IsEmpty(s))
		return NAN;
	else
		return s->top->next->data;
}


int pop_Ls(link_stack *s) {
	if (IsEmpty(s))
		return NAN;
	else {
		node *t = s->top->next;
		int x = t->data;
		s->top->next = t->next;
		delete t;

		s->length--;
		return x;
	}

}
void push_Ls(link_stack *s, int x) {

	node *t = new node;
	t->data = x;
	t->next = s->top->next;
	s->top->next = t;

	s->length++;
}

void Destroy(link_stack *s) {
	while (s->top != nullptr) {
		node *p = s->top->next;
		delete s->top;
		s->length--;
		s->top = p;
	}
}

③主函数文件:use.cpp

#include<iostream>
#include"link_stack.h"

int main() {
	using namespace std;

	link_stack s1;
	Init_Lstack(&s1);
	cout << "\nThe stack is empty: " << IsEmpty(&s1) << " \n";

	for (int i = 0; i < 7; i++) {
		push_Ls(&s1, i);
	}

	cout << "\nthe stack data: \n";
	node *t = s1.top;
	while (t->next != nullptr) {
		t = t->next;
		cout << t->data << "   ";
	}
	cout << endl;
	while (!IsEmpty(&s1)) {
		cout << pop_Ls(&s1) << endl;
	}

	getchar();
	return 0;
}

 

 

 若有错误,还望不吝指出,谢谢

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值