数据结构(第四篇:栈)

1、概述

栈是一种 后进先出 的特殊线性表,仅能在线性表的一端操作,栈顶允许操作,栈底不允许操作。如下图所示:
在这里插入图片描述

栈是一个逻辑结构,它是人为规定的底层的存储结构,可以是顺序结构,也可以是链式结构。使用顺序结构实现的栈叫做 静态栈(顺序栈)。使用链式结构实现的栈叫做 动态栈(链式栈)

栈的使用非常的普遍,在函数的调用,其实就是使用的栈。比如递归调用。

2、静态栈(顺序栈)

静态栈的缺点:当存储元素为类类型时,数组在创建时,会多次调用元素类型的构造函数,影响效率。
静态栈的优点:存储元素个数相同时,会占用较少内存。

静态栈的运算结构主要有:入栈、出栈。因为又固定大小的空间,所以要判断是不是满了,同时出栈时,需要判断是否有数据。下面是我书写的静态栈:

StaticStack.h

#pragma once
#define StackSize 10

class CStaticStack
{
public:
	CStaticStack();
	~CStaticStack();

	//判满
	bool IsFull();

	//判空
	bool IsEmpty();

	//入栈
	bool Push(int data);

	//出栈
	bool Pop(int& data);

	//按照出栈顺序打印
	void Print();

private:
	int m_iTop = 0;
	int m_data[StackSize];
};

StaticStack.cpp

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

CStaticStack::CStaticStack()
{
}


CStaticStack::~CStaticStack()
{
}

bool CStaticStack::IsFull()
{
	if ( m_iTop == StackSize )
	{
		return true;
	}

	return false;
}

bool CStaticStack::IsEmpty()
{
	if ( m_iTop == 0 )
	{
		return true;
	}

	return false;
}

bool CStaticStack::Push(int data)
{
	//先判断是不是满了
	if (IsFull())
	{
		return false;
	}

	m_data[m_iTop++] = data;
	return true;
}

bool CStaticStack::Pop(int& data)
{
	//先判断是不是空了
	if ( IsEmpty() )
	{
		return false;
	}

	data = m_data[--m_iTop];
	return true;
}

void CStaticStack::Print()
{
	int data;
	while ( Pop(data) )
	{
		std::cout << data << " ";
	}
}

测试用例:

int main(int argc, char** argv)
{
	int n, x;
	CStaticStack test;
	cout << "请输入元素个数n( 0 < n < 10):" << endl;
	cin >> n;
	cout << "请依次输入n个元素,依次入栈:" << endl;
	while (n--)
	{
		cin >> x; //输入元素
		test.Push(x);
	}

	cout << "元素依次出栈:" << endl;
	test.Print();

	getchar();
	getchar();
	return 0;
}

3、动态栈(链式栈)

动态栈的运算结构跟静态栈的差不多,但是因为没有数量的限制,所以没有判满的操作。另外增加了创建节点和删除节点的操作。下面是我自己写的实现:

DynamicStack.h

struct StackNode
{
	int data = 0;
	StackNode* pNext = nullptr;
};

class CDynamicStack
{
public:
	CDynamicStack();
	~CDynamicStack();
	
	//判空
	bool IsEmpty();

	//入栈
	bool Push(int data);

	//出栈
	bool Pop(int& data);

	//按照出栈顺序打印
	void Print();

private:
	bool CreatNode(StackNode*& pnode);

	void DestroyNode(StackNode*& pnode);

private:
	StackNode* m_pTop = nullptr;
};

DynamicStack.cpp

#include "DynamicStack.h"
#include <iostream>
      
CDynamicStack::CDynamicStack()
{
}   

CDynamicStack::~CDynamicStack()
{
	if ( m_pTop != nullptr )
	{
		while ( m_pTop )
		{
			StackNode* ptemp = m_pTop;
			m_pTop = m_pTop->pNext;
			DestroyNode(ptemp);
		}
	}
}

bool CDynamicStack::IsEmpty()
{
	return m_pTop == nullptr;
}

bool CDynamicStack::Push(int data)
{
	StackNode* ptemp = nullptr;
	if ( !CreatNode(ptemp) )
	{
		return false;
	}

	ptemp->data = data;
	ptemp->pNext = m_pTop;
	m_pTop = ptemp;

	return true;
}

bool CDynamicStack::Pop(int& data)
{
	if ( IsEmpty() )
	{
		return false;
	}

	data = m_pTop->data;
	StackNode* ptemp = m_pTop;
	m_pTop = m_pTop->pNext;
	DestroyNode(ptemp);

	return true;
}

void CDynamicStack::Print()
{
	int data;
	while (Pop(data))
	{
		std::cout << data << " ";
	}
}

bool CDynamicStack::CreatNode(StackNode*& pnode)
{
	StackNode* ptemp = new StackNode;
	if ( ptemp == nullptr )
	{
		return false;
	}

	pnode = ptemp;
	return true;
}

void CDynamicStack::DestroyNode(StackNode*& pnode)
{
	if ( pnode != nullptr )
	{
		delete pnode;
		pnode = nullptr;
	}
}

测试用例:

int main(int argc, char** argv)
{
	int n, x;
	CDynamicStack test;
	cout << "请输入元素个数n:" << endl;
	cin >> n;
	cout << "请依次输入n个元素,依次入栈:" << endl;
	while (n--)
	{
		cin >> x; //输入元素
		test.Push(x);
	}

	cout << "元素依次出栈:" << endl;
	test.Print();

	getchar();
	getchar();
	return 0;
}

感谢大家,我是假装很努力的YoungYangD(小羊)

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值