C++ 数据结构算法 学习笔记(17) - 栈的原理精讲 (1)

C++ 数据结构算法 学习笔记(17) - 栈的原理精讲 (1)

原理精讲

Jack 家的胡同很窄,只能通过一辆车,而且是死胡同,只能从胡同口进出,画图

在这里插入图片描述

胡同里的小汽车是排成一条直线,是线性排列,而且只能从一端进出,后进的汽车先出去,后进 先出(Last In First Out,LIFO),这就是"栈"。栈也是一种线性表,只不过它是操作受限的线性 表,只能在一端操作。 进出的一端称为栈顶(top),另一端称为栈底(base)。栈可以用顺序存储,也可以用链式存储。 我们先看顺序存储方式:

在这里插入图片描述

其中,base 指向栈底,top 指向栈顶。

注意:栈只能在一端操作,后进先出,这是栈的关键特征,也就是说不允许在中间查找、取值、插入、删除等 操作,我们掌握好顺序栈的初始化、入栈,出栈,取栈顶元素等操作即可。

顺序栈的算法实现

栈数据结构的定义

#define MaxSize 128 //预先分配空间,这个数值根据实际需要预估确定
typedef int ElemType;
typedef struct _SqStack{
ElemType *base; //栈底指针
ElemType *top; //栈顶指针
}SqStack;

栈的初始化

在这里插入图片描述

bool InitStack(SqStack &S) //构造一个空栈 S
{
	S.base = new int[MaxSize];//为顺序栈分配一个最大容量为 Maxsize 的空间
	if (!S.base) //空间分配失败
	return false;
	S.top=S.base; //top 初始为 base,空栈
	return true;
}

入栈

入栈操作:判断是否栈满,如果栈已满,则入栈失败,否则将元素放入栈顶,栈顶指针向上移动一个空间(top++)

在这里插入图片描述

bool PushStack(SqStack &S, int e) // 插入元素 e 为新的栈顶元素
{
	if (S.top-S.base == MaxSize) //栈满
		return false;
	*(S.top++) = e; //元素 e 压入栈顶,然后栈顶指针加 1,等价于*S.top=e;
	S.top++;
	return true;
}

出栈

出栈操作: 和入栈相反,出栈前要判断是否栈空,如果栈是空的,则出栈失败,否则将栈顶元素暂存给一个变 量,栈顶指针向下移动一个空间(top–)。

bool PopStack(SqStack &S, ElemType &e) //删除 S 的栈顶元素,暂存在变量 e中
{
	if (S.base == S.top)
    { 
		return false;
	}
	e = *(--S.top); //栈顶指针减 1,将栈顶元素赋给 e
	return true;
}

获取栈顶元素

取栈顶元素和出栈不同,取栈顶元素只是把栈顶元素复制一份,栈的元素个数不变,而出栈是指栈顶元素取出, 栈内不再包含这个元素。

ElemType GetTop(SqStack &S) //返回 S 的栈顶元素,栈顶指针不变
{
	if (S.top != S.base){ //栈非空
	return *(S.top - 1); //返回栈顶元素的值,栈顶指针不变
}
   else{
   	return -1;
	}
}

判断空栈

bool IsEmpty(SqStack &S){//判断栈是否为空
	if (S.top == S.base){
		return true;
	}
    else{
		return false;
	}
}

完整源码

完整源码实现

#include <Windows.h>
#include <iostream>
#include <stdlib.h>
using namespace std;
#define MaxSize 128 

typedef int ElemType;

typedef struct _SqStack {
	ElemType* base; 
	ElemType* top;
}SqStack;

bool InitStack(SqStack& S)
{
	S.base = new ElemType[MaxSize];

	if (!S.base) return false;
	S.top = S.base;
	return true;
}

bool PushStack(SqStack& S, ElemType e) 
{
	if (S.top - S.base == MaxSize) return false;
	*(S.top++) = e; 
	return true;
}

bool PopStack(SqStack& S, ElemType& e) 
{
	if (S.base == S.top) {
		return false;

	}
	e = *(--S.top);
	return true;
}

ElemType GetTop(SqStack& S) 
{
	if (S.top != S.base) { 
		return *(S.top - 1);
	}
	else {
		return -1;
	}
}

int GetSize(SqStack& S) {
	return (S.top - S.base);
}

bool IsEmpty(SqStack& S) {
	if (S.top == S.base) {
		return true;
	}
	else {
		return false;
	}
}

void DestoryStack(SqStack& S)
{
	if (S.base) {
		free(S.base);
		S.base = NULL;
		S.top = NULL;
	}
}

int main()
{
	int n, x;
	SqStack S;
	InitStack(S);
	cout << "Please enter the element number n:" << endl;
	cin >> n;
	cout << "Please accodingly enter the element to enter the stack:" << endl;

		while (n--)
		{
			cin >> x; 
			PushStack(S, x);
		}
	cout << "The element comeout from the stack:" << endl;
	while (!IsEmpty(S))
	{
		cout << GetTop(S) << "\t";
		PopStack(S, x); 
	}
	cout << endl;
	DestoryStack(S);
	system("pause");
	return 0;
}

课后练习

如果把栈的结构体定义改为链表形式, 该如何实现操作栈的算法呢?

完整代码实现

#include <iostream>
#include <string>

using namespace std;

#define MAX_SIZE	128
#define DataType int

typedef struct _List
{
	_List* next;
	DataType element;

}List;

typedef struct _SqList_Stack 
{

	List* top;
	int size;
	int capacity;

}SqList_Stack;

bool Init_Stack(SqList_Stack& stack)
{
	stack.size = 0;
	stack.capacity = MAX_SIZE;

	stack.top = new List;
	if (!stack.top) return false;
	stack.top->next = NULL;

	return true;
}

bool Empty_Stack(SqList_Stack& stack)
{
	if (stack.size == 0) return true;
	return false;
}

bool Full_Stack(SqList_Stack& stack)
{
	if (stack.size == stack.capacity) return true;
	return false;
}

bool Push_Stack(SqList_Stack& stack, DataType element_v)
{
	if (Full_Stack(stack)) return false;
	List* node = new List;
	node->element = element_v;
	node->next =stack.top->next;
	stack.top->next = node;
	stack.size++;
	return true;
}

bool Pop_Stack(SqList_Stack& stack, DataType* element_v)
{
	if (Empty_Stack(stack)) return false;
	List* tmp = stack.top->next;
	*element_v = tmp->element;
	stack.top->next = tmp->next;
	delete tmp;
	stack.size--;
	return true;
}

bool Get_Head(SqList_Stack& stack, DataType* element_v)
{
	if (Empty_Stack(stack)) return false;
	List* tmp = stack.top->next;
	*element_v = tmp->element;
	return true;
}

int GetSize(SqList_Stack& stack)
{
	return stack.size;
}

void Destroy_Stack(SqList_Stack& stack)
{
	List* tmp = stack.top;
	while (tmp)
	{
		List* next = tmp->next;
		delete tmp;
		tmp = next;
	}
	stack.top = NULL;
	stack.size = 0;
}

int main()
{

	int n, x;
	SqList_Stack S;
	int element;
	Init_Stack(S);
	cout << "Please enter the element number n:" << endl;
	cin >> n;
	cout << "Please accodingly enter the element to enter the stack:" << endl;

	while (n--)
	{
		cin >> x;
		Push_Stack(S, x);
	}
	cout << "The element comeout from the stack:" << endl;
	while (!Empty_Stack(S))
	{
		Get_Head(S, &element);
		cout << element << "\t";
		Pop_Stack(S, &x);
	}
	cout << endl;
	cout << "Ending the print function" << endl;
	Destroy_Stack(S);
	system("pause");
	return 0;
}
  • 4
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值