python-数据结构与算法分析-基本数据结构-队列+链表

这篇博客介绍了数据结构中的队列、双端队列和链表的实现。队列采用列表实现,遵循先进先出原则;双端队列允许在两端进行插入和删除;链表包括无序链表和有序链表,无序链表每次在头部插入,有序链表则保持插入的有序性。此外,还展示了如何使用两个栈实现队列的基本操作。
摘要由CSDN通过智能技术生成

队列

满足first-in-first-out,包含以下函数:

  • Queue() 创建空队列
  • enqueue(item) 在尾部添加一个元素
  • dequeue() 从头部移除一个元素,并返回这个值
  • isEmpty() 检查是否为空,返回bool
  • size() 返回元素数目
class Queue:
    def __init__(self):
        self.items = []

    def isEmpty(self):
        return self.items == []

    def enqueue(self, item):
        self.items.insert(0, item)

    def dequeue(self):
        return self.items.pop()

    def size(self):
        return len(self.items)

if __name__ == "__main__":
    q = Queue()
    q.enqueue(4)
    q.enqueue(2)
    print(q.dequeue())
    print(q.size())

双端队列

deque(与deck同音),两端都可以添加和移除元素。
这里将items的尾部作为deque的头,实现:

class Deque:
    def __init__(self):
        self.items = []

    def isEmpty(self):
        return self.items == []

    def addFront(self, item):
        self.items.append(item)

    def addRear(self, item):
        self.items.insert(0, item)

    def removeFront(self):
        return self.items.pop()

    def removeRear(self):
        return self.items.pop(0)

    def size(self):
        return len(self.items)

链表

无序链表

无序列表每次在头部插入,然后令新值(新节点)为新的head。
在这里插入图片描述

class Node:
    def __init__(self, initdata):
        self.data = initdata
        self.next = None

    def getData(self):
        return self.data

    def getNext(self):
        return self.next

    def setData(self, newData):
        self.data = newData

    def setNext(self, newNext):
        self.next = newNext

class UnorderedList:
    def __init__(self):
        self.head = None

    def isEmpty(self):
        return self.head == None

    '''
    因为只知道一个head,所以自然要把新元素放在头部,
    并让新元素成为新的head
    '''
    def add(self, item):
        temp = Node(item)
        temp.setNext(self.head)
        self.head = temp

    '''
    获取列表长度需要遍历列表
    '''
    def length(self):
        current = self.head
        count = 0
        while current != None:
            count += 1
            current = current.getNext()
        return count

    '''
    查找元素也需要遍历
    '''
    def search(self, item):
        current = self.head
        isFound = False
        while current != None and not isFound:
            if current.getData() == item:
                isFound = True
            else:
                current = current.getNext()
        return isFound

    def remove(self, item):
        current = self.head
        pre = None
        isFound = False
        while not isFound and current != None:
            if current.getData() == item:
                isFound = True
            else:
                pre = current
                current = current.getNext()
        if not isFound: # 找不到就不修改
            return
        if pre == None: # 表示第一个就是item
            self.head = current.getNext()
        else:
            pre.setNext(current.getNext())



if __name__ == "__main__":
    li = UnorderedList()
    li.add(31)
    li.add(40)
    li.add(7)
    print(li.isEmpty())
    print(li.length())
    print(li.search(-1))
    li.remove(-1)
    print(li.length())
    li.remove(40)
    print(li.length())
'''
False
3
False
3
2
'''

有序链表

有序列表强调插入时有序,比如头部最小,每次插入值时都去找比待插入值大的最小值。查找时只要遇到比待查找值大的节点,那么后面都比待查值大,因此不必再遍历。
在这里插入图片描述
这里重写查找和插入:

    def search_orderly(self, item):
        current = self.head
        isFound = False
        while current != None and not isFound:
            if current.getData() == item:
                isFound = True
                break
            else:
                if current.getData() > item:
                    break
                else:
                    current = current.getNext()
        return isFound
        
    def add_orderly(self, item):
        current = self.head
        pre = None
        while current != None:
            if current.getData() > item:
                break
            else:
                pre = current
                current = current.getNext()
        temp = Node(item)
        # 如果要在头部插入
        if pre == None:
            temp.setNext(self.head)
            self.head = temp
        else:
            temp.setNext(current)
            pre.setNext(temp)

练习

232. 用栈实现队列

请你仅使用两个栈实现先入先出队列。队列应当支持一般队列支持的所有操作(push、pop、peek、empty):

实现 MyQueue 类:
void push(int x) 将元素 x 推到队列的末尾
int pop() 从队列的开头移除并返回元素
int peek() 返回队列开头的元素
boolean empty() 如果队列为空,返回 true ;否则,返回 false

说明:你 只能 使用标准的栈操作 —— 也就是只有 push to top, peek/pop from top, size, 和 is empty 操作是合法的。
你所使用的语言也许不支持栈。你可以使用 list 或者 deque(双端队列)来模拟一个栈,只要是标准的栈操作即可。

示例 1:
输入:
[“MyQueue”, “push”, “push”, “peek”, “pop”, “empty”]
[[], [1], [2], [], [], []]
输出:
[null, null, null, 1, 1, false]

解释:
MyQueue myQueue = new MyQueue();
myQueue.push(1); // queue is: [1]
myQueue.push(2); // queue is: [1, 2] (leftmost is front of the queue)
myQueue.peek(); // return 1
myQueue.pop(); // return 1, queue is [2]
myQueue.empty(); // return false

思路:
使用两个list模拟stack。push时将元素压入s1,peek时,如果s2非空,直接返回栈顶,否则将s1的元素压入s2中;pop时先操作移动元素,然后移除s2栈顶。

class MyQueue:

    def __init__(self):
        self.s1 = []
        self.s2 = []


    def push(self, x: int) -> None:
        self.s1.append(x)


    def pop(self) -> int:
        self.peek()
        return self.s2.pop()


    def peek(self) -> int:
        if len(self.s2) == 0:
            while len(self.s1) != 0:
                self.s2.append(self.s1.pop()) 
        return self.s2[-1]


    def empty(self) -> bool:
        return len(self.s1) == 0 and len(self.s2) == 0


# Your MyQueue object will be instantiated and called as such:
# obj = MyQueue()
# obj.push(x)
# param_2 = obj.pop()
# param_3 = obj.peek()
# param_4 = obj.empty()
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值