Python使用列表与链表分别来实现堆栈和队列

堆栈:先进后出,队列:先进先出

堆栈是一种线性表,只能在表尾进行插入和删除操作,这个表尾就是栈顶另一端就是栈底。那么向堆栈插入新元素就叫做入栈、进栈或压栈,也就是将新元素放到栈顶;反之出栈时,就是把栈顶元素删除,使其相邻元素成为新的栈顶。

队列也是一种线性表,只允许在表的前端(front)进行删除操作,在表的后端(rear)进行插入操作,和栈一样,队列是一种操作受限制的线性表。进行插入操作的端称为队尾,进行删除操作的端称为队头。

下面我们通过多种方法来实现,让初学者更熟悉这两种数据结构。

列表实现堆栈(顺序栈)

class Stack:
    #初始化一个列表,定义一个大小
    def __init__(self):
        self.stack=[]
        self.size=0
    #打印的时候,方便输出这个字符串
    def __str__(self):
        return str(self.stack)

    #入栈
    def push(self,data):
        self.stack.append(data)
        self.size+=1

    #出栈
    def pop(self):
        if self.stack is not None:
            tmp=self.stack.pop()
            self.size-=1
        return tmp
    
    #栈顶元素
    def top(self):
        if self.stack is not None:
            return self.stack[-1]
    #是否空栈
    def is_empty(self):
        return not bool(self.stack)


stack=Stack()
stack.push(1)
stack.push(2)
stack.push('寅恪光潜')
stack.push(3)
stack.push('Tony')
stack.pop()
stack.pop()
#print(stack.stack)
print(stack,stack.size,stack.is_empty(),stack.top())
#[1, 2, '寅恪光潜'] 3 False 寅恪光潜

链表实现堆栈(链式栈)

from typing import Any, NoReturn, Optional

#定义一个结点类
class Node:
    #Any指任意类型,Optional为可选类型,先设置为空
    def __init__(self,data:Any,next:Optional=None):
        self.data:Any=data
        self.next:Optional[Node]=next
    #方便打印显示    
    def __str__(self):
        return "Node:%s" % self.data
    

class LinkedStack:
    #栈顶初始化为空,大小为0
    def __init__(self)->NoReturn:
        self.top=None
        self.size=0

    #入栈
    def push(self,item:Any)->None:
        node=Node(item)#生成结点数据
        #如果栈顶有数据,将栈顶数据向下移动,然后栈顶接收新数据
        #如果栈顶为空,将新数据赋值给栈顶
        if self.top:
            node.next=self.top
            self.top=node
        else:
            self.top=node
        self.size+=1

    #出栈
    def pop(self)->Any:
        #如果栈顶有节点,将下一个结点赋值到栈顶
        #如果栈顶为空,不能出栈
        if self.top:
            node:Node=self.top
            self.top=node.next
            self.size-=1
            return node.data
        else:
            raise IndexError("空栈不能有出栈操作")
    
    #是否空栈
    def is_empty(self)->bool:
        return self.top is None

    #重构,与__str__有些许区别
    def __repr__(self):
        current=self.top
        string_repr=""
        while current:
            string_repr+=f"{current} --> "
            current=current.next
        return string_repr +"栈底"

linedstack=LinkedStack()
linedstack.push(11)
linedstack.push(22)
linedstack.pop()
linedstack.push('寅恪光潜')
linedstack.push('Tony')
linedstack.push(33)
print(linedstack)
print(linedstack.size)

'''
Node:33 --> Node:Tony --> Node:寅恪光潜 --> Node:11 --> 栈底
4
'''

其中在方法名后面出现 ->返回类型,它是对返回类型的一种注解,如下,比如可以获取查看push方法的类型

print(linedstack.push.__annotations__)#{'item': typing.Any, 'return': None}

然后我们来看下怎么实现队列,熟悉上面之后,写起来就很简单了。

列表实现队列

class Queue:
    def __init__(self):
        self.enteries=[]
        self.length=0
        self.front=0

    def __str__(self):
        return "<"+str(self.enteries)[1:-1]+">"

    #入队
    def put(self,item):
        self.enteries.append(item)
        self.length +=1

    #出队,返回第一个,只保留从第二个开始的数据
    def get(self):
        dequeued=self.enteries[self.front]
        self.enteries=self.enteries[1:]
        self.length=self.length-1
        return dequeued

    def size(self):
        return self.length
    
queue=Queue()
queue.put("One")
queue.put("Two")
queue.put("Three")
queue.get()
queue.put("Tony")
print(queue)
print(queue.size())
print(queue.enteries[0])

'''
<'Two', 'Three', 'Tony'>
3
Two
'''

链表实现队列

from typing import Any, Optional

class Node:
    #Any指任意类型,Optional为可选类型,先设置为空
    def __init__(self,data:Any,next:Optional=None):
        self.data:Any=data
        self.next:Optional[Node]=next
    #方便打印显示    
    def __str__(self):
        return "Node:%s" % self.data

class LinkedQueue:
    def __init__(self)->None:
        self.front:Optional[Node]=None
        self.rear:Optional[Node]=None
        self.size=0
    
    #入队,就是节点后面的下一节点接收新节点数据
    def put(self,item:Any)->None:
        node:Node=Node(item)
        if self.is_empty():
            self.front=node
            self.rear=node
        else:
            self.rear.next=node
            self.rear=node
            self.size +=1

   #出队,就是下一节点放在前面,向前推进一位
    def pop(self):
        if self.is_empty():
            raise IndexError("空队列不能出队操作")
        else:
            node:Node=self.front
            self.front=node.next
            self.size-=1

    def is_empty(self)->bool:
        return self.front is None
   
    def __repr__(self):
        current=self.front
        string_repr=""
        while current:
            string_repr +=f"{current}<--"
            current=current.next
        return string_repr+"队列尾部"

linkedqueue=LinkedQueue()
linkedqueue.put("One")
linkedqueue.put("Tony")
linkedqueue.put("寅恪光潜")
linkedqueue.put("Two")
linkedqueue.put("Three")
linkedqueue.pop()
print(linkedqueue)
'''
Node:Tony<--Node:寅恪光潜<--Node:Two<--Node:Three<--队列尾部
'''

你可能感兴趣的:(Python,链表,数据结构,堆栈,队列)