- C#程序员面试算法宝典
- 猿媛之家组编 赵大有等编著
- 755字
- 2021-03-29 04:07:37
2.1 如何实现栈
难度系数:★★★☆☆ 被考察系数:★★★★☆
题目描述:
实现一个栈的数据结构,使其具有以下方法:压栈、弹栈、取栈顶元素、判断栈是否为空以及获取栈中元素个数。
分析与解答:
栈的实现有两种方法,分别为采用数组来实现和采用链表来实现。下面分别详细介绍这两种方法。
方法一:数组实现
在采用数组来实现栈的时候,栈空间是一段连续的空间。实现思路如下图所示。
![](https://epubservercos.yuewen.com/FBAA2E/17977546208666906/epubprivate/OEBPS/Images/978-7-111-65153-6_70_01.jpg?sign=1739171083-DqMb0T2xplZNvc6T6NvKzJZ8KyNELHY7-0-8ee63e22ceb9b0281805ed8eaa12acca)
从上图中可以看出,可以把数组的首元素当做栈底,同时记录栈中元素的个数 size,假设数组首地址为arr,从上图可以看出,压栈的操作其实是把待压栈的元素放到数组Arr[size]中,然后执行size++操作;同理,弹栈操作其实是取数组Arr[size-1]元素,然后执行 size--操作。根据这个原理可以非常容易实现栈,示例代码如下:
![](https://epubservercos.yuewen.com/FBAA2E/17977546208666906/epubprivate/OEBPS/Images/978-7-111-65153-6_70_02.jpg?sign=1739171083-zBW9NZr0m8UCrgkwKOp5KmgXQWCIg4Ym-0-87993553b7599a2595bb2ab81f0c6dfe)
![](https://epubservercos.yuewen.com/FBAA2E/17977546208666906/epubprivate/OEBPS/Images/978-7-111-65153-6_71_01.jpg?sign=1739171083-csGcNloFdNhokxYMlFkvDRBC1U3qKGcY-0-d0a6d42a1c4e8d43be597149427bed8b)
方法二:链表实现
在创建链表的时候经常采用一种从头结点插入新结点的方法,可以采用这种方法来实现栈,最好使用带头结点的链表,这样可以保证对每个结点的操作都是相同的,实现思路如下图所示:
![](https://epubservercos.yuewen.com/FBAA2E/17977546208666906/epubprivate/OEBPS/Images/978-7-111-65153-6_71_02.jpg?sign=1739171083-doW2dC3R7QPj1K9ikuLd92bZJAQPftd6-0-bffca406bce2a2e79543de127b67242f)
在上图中,在进行压栈操作的时候,首先需要创建新的结点,把待压栈的元素放到新结点的数据域中,然后只需要步骤(1)和步骤(2)两步就实现了压栈操作(把新结点加到了链表首部)。同理,在弹栈的时候,只需要进行步骤(3)的操作就可以删除链表的第一个元素,从而实现弹栈操作。实现代码如下所示:
![](https://epubservercos.yuewen.com/FBAA2E/17977546208666906/epubprivate/OEBPS/Images/978-7-111-65153-6_72_01.jpg?sign=1739171083-XmwP4h0MWZSnzQMhkZoFe3qxYC9VeeWQ-0-8202023b46a083eb67c5eb0f5c5776d7)
![](https://epubservercos.yuewen.com/FBAA2E/17977546208666906/epubprivate/OEBPS/Images/978-7-111-65153-6_73_01.jpg?sign=1739171083-xJXm63R1ZPriMpI7L6xQycUj8rBd4fYw-0-0c50a90d46ae3e15333e60c5d8d3d332)
程序的运行结果为
![](https://epubservercos.yuewen.com/FBAA2E/17977546208666906/epubprivate/OEBPS/Images/978-7-111-65153-6_73_02.jpg?sign=1739171083-WtjdU5k3340VENPDORiNT298JHrYLDar-0-ccd06436dae4e8697dca8d9864f4c135)
![](https://epubservercos.yuewen.com/FBAA2E/17977546208666906/epubprivate/OEBPS/Images/978-7-111-65153-6_74_01.jpg?sign=1739171083-yaoH658hJ1znSeJ8l1F6a97TVJuLFGoe-0-c7dc29c01a012225897f27ce14335967)
两种方法的对比:
采用数组实现栈的优点是:一个元素值占用一个存储空间;它的缺点为:如果初始化申请的存储空间太大,会造成空间的浪费,如果申请的存储空间太小,后期会经常需要扩充存储空间,扩充存储空间是个费时的操作,这样会造成性能的下降。
采用链表实现栈的优点是:使用灵活方便,只有在需要的时候才会申请空间。它的缺点为:除了要存储元素外,还需要额外的存储空间存储指针信息。
算法性能分析:
这两种方法压栈与弹栈的时间复杂度都为O(1)。