Python实现栈的方法详解【基于数组和单链表两种

1. 栈的定义和基本操作

栈是一个后进先出(LIFO,Last In First Out)的数据结构,它可以用数组或链表实现。栈的基本操作有入栈(Push)和出栈(Pop),以及查询栈顶元素(Top)和判断栈是否为空(IsEmpty)。

2. 数组实现栈

数组实现栈通常需要先定义一个固定大小的数组,然后通过顶部指针来追踪栈顶的位置,入栈操作就是将元素添加到栈顶,同时将顶部指针向上移动,出栈操作则是删除栈顶元素,同时将顶部指针向下移动。

2.1 数组实现栈的初始化

class Stack:

def __init__(self, capacity):

self.capacity = capacity

self.stack = [None] * capacity

self.top = -1

capacity表示栈的最大容量,stack是一个固定大小的数组,用来储存栈中的元素,top表示当前栈顶的位置,初始值为-1。

2.2 数组实现栈的入栈操作

class Stack:

...

def push(self, value):

if self.top == self.capacity - 1:

raise Exception('Stack overflow')

self.top += 1

self.stack[self.top] = value

入栈操作先检查栈是否已满,如果是,则抛出异常。否则,将顶部指针向上移动,并将元素添加到栈顶。

2.3 数组实现栈的出栈操作

class Stack:

...

def pop(self):

if self.top == -1:

raise Exception('Stack underflow')

value = self.stack[self.top]

self.top -= 1

return value

出栈操作先检查栈是否为空,如果是,则抛出异常。否则,将元素从栈顶删除,并将顶部指针向下移动。

2.4 数组实现栈的其他操作

除了入栈和出栈操作外,数组实现栈还可以实现查询栈顶元素和判断栈是否为空。查询栈顶元素可以通过返回数组中顶部指针对应的元素,而判断栈是否为空只需要检查顶部指针的值是否为-1。

class Stack:

...

def top(self):

if self.top == -1:

return None

return self.stack[self.top]

def is_empty(self):

return self.top == -1

3. 链表实现栈

链表实现栈通常需要定义一个链表结构来储存元素,入栈操作就是将元素添加到链表的头部,出栈操作则是删除链表头部的元素。

3.1 链表实现栈的初始化

class Node:

def __init__(self, value):

self.value = value

self.next = None

class Stack:

def __init__(self):

self.top = None

链表实现栈中,Node类表示一个链表节点,它包含一个值和一个指向下一个节点的指针。而Stack类通过储存链表的头节点来追踪栈顶位置,top初始值为None。

3.2 链表实现栈的入栈操作

class Stack:

...

def push(self, value):

node = Node(value)

node.next = self.top

self.top = node

入栈操作先创建一个新节点,并将其指向原来的头节点。然后将链表头节点指向新节点。

3.3 链表实现栈的出栈操作

class Stack:

...

def pop(self):

if not self.top:

raise Exception('Stack underflow')

value = self.top.value

self.top = self.top.next

return value

出栈操作先判断链表是否为空,如果是则抛出异常。否则,将链表头节点删除,并将头节点指向当前节点的下一个节点。

3.4 链表实现栈的其他操作

和数组实现栈类似,链表实现栈也可以实现查询栈顶元素和判断栈是否为空。查询栈顶元素可以通过返回链表头部节点对应的元素,而判断栈是否为空只需要检查头部节点的值是否为None。

class Stack:

...

def top(self):

if not self.top:

return None

return self.top.value

def is_empty(self):

return not self.top

4. 总结

数组和链表都可以用来实现栈,并且它们在时间和空间复杂度上有所不同。数组实现栈可以提供更快的访问时间,但缺点是必须预先分配一定大小的存储空间,并且在入栈时可能需要进行数据迁移。链表实现栈不需要进行数据迁移,并且可以动态扩展,但缺点是可能需要更多的内存来储存指针。在实际应用中,应根据具体情况选择合适的实现方式。

后端开发标签