C++栈的顺序存储(可扩展空间)和链式存储

是一种常见的数据结构,它具有后进先出(LIFO)的特性,即最后入栈的元素最先出栈。

栈的顺序存储是指使用数组来实现栈的存储结构。在顺序存储中,栈的底部对应数组的起始位置,栈的顶部对应数组的末尾位置。当元素入栈时,将元素放置在栈顶位置,栈顶指针向上移动;当元素出栈时,将栈顶元素移除,并将栈顶指针向下移动。

栈的链式存储是指使用链表来实现栈的存储结构。在链式存储中,栈中的每个元素被视为链表的节点,节点包含一个数据域和一个指向下一个节点的指针。入栈操作将新元素插入链表的头部,将链表的头指针指向新的节点;出栈操作将头部的节点删除,并将链表的头指针指向下一个节点。

由于栈的运算方式受限,一般来说顺序栈的应用更加广泛。

顺序存储

栈的存储结构

template <typename T>
class MyStack
{
public:
	MyStack(int _stack_capacity = 8);//默认参数在声明处说明即可
	~MyStack();

	void Push(const T& _data);//入栈
	void Pop();//删除
	T& Top();//返回栈顶数据
	bool Empty();//判断栈是否为空
	int Size();//返回栈的大小
	void print();

private:
	T* stack;//栈指针
	int top;//栈顶位置
	int stack_capacity;//栈的大小
	
	void ChangeSize();//栈的扩容函数
};

顺序栈的方法

//构造函数和析构函数
template <typename T>
MyStack<T>::MyStack(int _stack_capacity):stack_capacity(_stack_capacity)
{
	stack = new T[stack_capacity];//生成一个大小为stack_capacity的栈
	top = -1;
}
template <typename T>
MyStack<T>::~MyStack()
{
	delete[] stack;
}
//入栈
template <typename T>
void MyStack<T>::Push(const T& _data)
{
	if (top == stack_capacity - 1) 
	{//判断栈是否满了
		ChangeSize();//扩容
	}
	stack[++top] = _data;
}
//出栈
template <typename T>
void MyStack<T>::Pop()
{
	if (!Empty())
		top--;
	else
		exit(1);
}
//获取栈顶数据
template <typename T>
T& MyStack<T>::Top()
{
	if (!Empty())
		return stack[top];//非空就返回栈顶数据
	else
		exit(1);
}
//判空
template <typename T>
bool MyStack<T>::Empty()
{
	if (top < 0)
		return true;
	else
		return false;
}
//栈的大小
template <typename T>
int MyStack<T>::Size()
{
	return (top + 1);
}
template<typename T>
void MyStack<T>::print()
{
	while (top != 0)
	{
		cout << stack[top];
		top--;
	}
	cout << stack[top];
}

顺序栈的扩容

由于顺序栈使用数组进行定义,在初始化时无法像链栈一样动态分配空间,当空间用完时只能手动扩容

扩容函数

template <typename T>
void  MyStack<T>::ChangeSize()
{
	cout << "栈扩容" << endl;
	int size = stack_capacity * 2;//栈容量扩大1倍

	T* tmp = new T[size];//1.申请一块原来2倍大小的空间。
	copy(stack, stack + stack_capacity, tmp);//2.将栈中的数据赋值到新的内存空间
	delete[] stack;//3.删除老的空间
	stack = tmp;//4.stack指向新地址
	stack_capacity = size;//5.改变stack_capacity大小
}

大体思路是分配一块空间使这块空间是以前的两倍(更加高效),然后将原来的栈中的数据复制到新的空间中去,将原来的栈指针指向新分配的空间。

栈的应用(进制转化)

int main()
{
	MyStack<int>Q;
	int data;
	cout << "请输入你要转化的数据" << endl;
	cin >> data;
	while (data)
	{
		Q.Push(data % 2);
		data /= 2;
	}
	Q.print();
}

当数据转化后长度大于预设(8)会自动扩容如下图

链栈

链栈的存储格式

template<typename T>
class template_class
{
private:
	T data;
public:
	
	template_class<T>*top;
	template_class<T>* next;
public:
	template_class();
	~template_class();
public:
	void print();
	void push(T data);
	void pop(T data);
	void Change(T data);
	void Search(T data);
};

链栈的方法

template<typename T>
inline template_class<T>::template_class()
{
	this->next = NULL;
	this->top = NULL;
}

template<typename T>
inline template_class<T>::~template_class()
{
	if (top == NULL)
	{
		
		return;
	}
	else
	{
		template_class<T>* pcurrent = top;
		template_class<T>* curr = NULL;
		while (pcurrent->next != NULL)
		{
			curr = pcurrent;
			pcurrent = pcurrent->next;
			delete curr;
			curr = NULL;
		}
		delete pcurrent;
		pcurrent = NULL;
	}
}

template<typename T>
inline void template_class<T>::print()
{
	if (top == NULL)
	{
		cout << "没有数据" << endl;
		return;
	}
	else
	{
		template_class<T>* pcurrent = top;
		while (pcurrent->next != NULL)
		{
			cout << pcurrent->data << endl;
			pcurrent = pcurrent->next;
		}
		cout << pcurrent->data << endl;
		return;
	}
}

template<typename T>
inline void template_class<T>::push(T data)
{
	template_class<T>* pcurrent = new template_class<T>;
	pcurrent->data = data;
	if (top == NULL)
	{
		top = pcurrent;
	}
	else
	{
		pcurrent->next = top;
		top = pcurrent;
	}
}

template<typename T>
inline void template_class<T>::pop(T data)
{
	if (top == NULL)
	{
		
		return;
	}
	if (top != NULL && top->next == NULL)
	{
		data = top->data;
		delete top;
		top = NULL;
	}
	if (top != NULL && top->next != NULL)
	{
		template_class<T>* curr = top;
		top = top->next;
		data = curr->data;
	
	}
}

template<typename T>
inline void template_class<T>::Change(T data)
{
	template_class<T>* pcurrent = top;
	if (top == NULL)
	{
		cout << "没有数据" << endl;
		return;
	}
	else
	{
		while (pcurrent->data != data)
		{
			pcurrent = pcurrent->next;
		}
		if (pcurrent->next == NULL && pcurrent->data != data)
		{
			cout << "没有目标数据" << endl;
			return;
		}
		else
		{
			T da;
			cout << "请输入数据" << endl;
			cin >> da;
			pcurrent->data = da;
			cout << "更改成功" << endl;
			return;
		}
	}
}

template<typename T>
inline void template_class<T>::Search(T data)
{
	/*template_class<T>* pcurrent = top;
	while (pcurrent->data != data)
	{
		pcurrent = pcurrent->next;
	}
	if (pcurrent->next == NULL && pcurrent->data != data)
	{
		cout << "没有目标数据" << endl;
		return;
	}
	if (pcurrent->next == NULL && pcurrent->data == data)
	{
		cout << pcurrent->data << endl;
		return;
	}
	cout << pcurrent->data << endl;*/

	template_class<T>* pcurrent = top;
	if (top == NULL)
	{
		cout << "没有数据" << endl;
		return;
	}
	else
	{
		while (pcurrent->data != data)
		{
			pcurrent = pcurrent->next;
		}
		if (pcurrent->next == NULL && pcurrent->data != data)
		{
			cout << "没有目标数据" << endl;
			return;
		}
		else
		{
			cout << pcurrent->data << endl;
		}
	}
}

 总的来说链栈就是运算受限的链表(一般是单链表,也可以使用双向链表实现),它的操作比较简单,但是存储密度很小,且发挥不出链表该有的灵活性,因此不是很常见。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值