简单的数组栈

//程序编译运行通过,基本结构写好了。
//travel,size,expand等函数可以慢慢扩展

#include <iostream>
using namespace std;
typedef int T;
class Stack
{
private:
	T data[5];
	int sz;  //数组个数
public:
	Stack():sz()  //只需将sz初始化为0就行了,data不用
	{

	}

	bool isFull() const 
	{
		return 5==sz;
	}

	bool isEmpty() const
	{
		return 0==sz;
	}

	void push(const T& d)
	{
		if(isFull())
		{
			throw "满" ;
		}
		data[sz++] = d;
	}

	void pop() 
	{
		if(isEmpty())
		{
			throw "空";
		}
		sz--;
	}

	T top() const
	{
		if(isEmpty())
		{
			throw "空";
		}
		return data[sz-1];
	}

	
};

int main()
{
	Stack s;
	s.push(11);
	s.push(22);
	s.push(33);	
	s.push(44);
	s.push(55);
	cout << s.top() << endl;
	s.pop();
	cout << s.top() << endl;
	
	//如果这里有个遍历函数,会比较方便,到处可以用。
	while(!s.isEmpty())
	{
		cout << s.top() << ' ';
		s.pop();
	}
	cout << endl;
}

### 数组与链表的区别 数组和链表是两种常见的实现方式,它们在底层数据结构、内存管理、性能特点等方面存在显著差异。 #### 实现方式 数组使用固定大小的数组来存储中的元素,通过一个顶指针(`_top`)来标识当前顶的位置。当元素被压入时,顶指针递增;当元素被弹出时,顶指针递减。如果满时继续压入元素,则需要进行扩容操作[^4]。 链表则使用链表来实现,每个节点包含一个数据元素和一个指向下一个节点的指针。顶通常位于链表的头部,每次压操作只需在链表头部插入新节点,而弹操作则移除头部节点。这种方式避免了固定容量的限制[^3]。 #### 优缺点比较 **数组的优点**: - **访问速度快**:由于数组在内存中是连续存储的,因此可以通过索引快速访问任意位置的元素。 - **缓存友好**:数组的连续性使得它在CPU缓存中的表现更好,有助于提高程序运行效率。 - **实现简单**:数组的实现相对简单,尤其是在不需要动态扩容的情况下。 **数组的缺点**: - **容量固定**:除非手动处理,否则数组的容量是固定的,这可能导致空间浪费或溢出问题。 - **扩容成本高**:当数组满时,必须创建一个新的更大的数组并将所有旧数据复制过去,这个过程会消耗额外的时间和资源[^2]。 **链表的优点**: - **动态大小**:链表可以根据需要动态地增加或减少其大小,没有预分配空间的问题。 - **插入删除高效**:在链表头部进行插入和删除操作的时间复杂度为 O(1),非常适合用作的实现基础。 - **灵活的内存管理**:每个节点都是独立分配的,所以可以更有效地利用内存空间。 **链表的缺点**: - **访问速度慢**:不能直接访问中间或尾部的元素,只能从头开始遍历,导致随机访问效率低下。 - **额外开销**:每个节点都需要额外的空间来保存指向下个节点的指针,增加了内存占用量。 - **实现复杂度较高**:相比数组,链表的实现更为复杂,特别是在涉及内存管理和错误检查时[^3]。 #### 性能对比 对于大多数应用场景来说,选择哪种实现取决于具体的需求。如果应用对性能有极高要求且数据规模已知,那么数组可能是更好的选择。然而,在那些需要频繁调整大小或者不确定数据量的情况下,链表提供了更高的灵活性和适应性[^1]。 例如,在C语言中,数组的一个典型实现可能如下所示: ```c #define _CRT_SECURE_NO_WARNINGS 1 #include <stdio.h> #include <assert.h> #include <stdlib.h> typedef int STDataType; typedef struct Stack { STDataType* _a; int _top; // 顶 int _capacity; // 容量 } Stack; // 初始化 void StackInit(Stack* ps) { ps->_a = (STDataType*)malloc(sizeof(STDataType) * 4); // 初始容量设为4 assert(ps->_a != NULL); ps->_top = 0; ps->_capacity = 4; } // 入 void StackPush(Stack* ps, STDataType data) { if (ps->_top == ps->_capacity) { // 如果满,则扩容 int new_capacity = ps->_capacity * 2; STDataType* new_a = (STDataType*)realloc(ps->_a, sizeof(STDataType) * new_capacity); assert(new_a != NULL); ps->_a = new_a; ps->_capacity = new_capacity; } ps->_a[ps->_top++] = data; } // 出 void StackPop(Stack* ps) { assert(ps->_top > 0); // 确保非空 --ps->_top; } // 获取顶元素 STDataType StackTop(const Stack* ps) { assert(ps->_top > 0); // 确保非空 return ps->_a[ps->_top - 1]; } // 获取中有效元素个数 int StackSize(const Stack* ps) { return ps->_top; } // 检测是否为空 int StackEmpty(const Stack* ps) { return ps->_top == 0; } // 销毁 void StackDestroy(Stack* ps) { free(ps->_a); ps->_a = NULL; ps->_top = 0; ps->_capacity = 0; } ``` 这段代码展示了一个支持动态增长的数组实现,其中包含了初始化、入、出等基本操作。通过 `realloc` 函数实现了当满时自动扩容的功能。这种实现方式兼顾了数组的快速访问特性和一定的灵活性。 相比之下,链表的实现虽然稍微复杂一些,但它能够提供更加灵活的内存使用模式,并且在频繁插入删除操作下表现出色。根据实际需求以及对性能和内存使用的考量,开发者可以选择最适合当前项目的实现方式[^4]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值