数据结构和算法-列表

Posted zlone

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了数据结构和算法-列表相关的知识,希望对你有一定的参考价值。

队列和栈相反

  • 队列: 先进先出(FIFO)
  • 栈: 后进先出(LIFO)

类型

  • 循环队列
    • Disruptor高性能队列
  • 并发队列(线程安全)
  • 阻塞队列

顺序队列

使用python的list结构来模拟, 在右端插入的话时间复杂度是O(n), 在左端弹出的话是O(1)

方式一: 每次出队操作都要移动数组

# coding:utf-8

"""
使用列表模拟单端队列

左出右进
"""


class Queue(object):
    """
    使用列表模拟实现单端队列
    """

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

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

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

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

    def dequeue(self):
        """
        每次出队所有元素都会向前移动
        :return:
        """
        if self.isEmpty():
            raise Exception("empty queue")
        res = self.items.pop(0)
        return res

方式二

技术图片

每次出队时不用再移动所有元素, 只有当入队时如果tail指针在最尾部, 检测数组是否还有空间

  • 如果还有空间, 移动所有元素后再添加
  • 如果没有空间, 返回错误
# coding:utf-8


class Queue(object):
    """
    队列

    使用固定数组的形式, 优点是出队操作不用再每次都移动数组

    只有当入队操作的时候, 如果数组内还有空余位置, 但是tail已经在最尾部了, 此时需要进行数据搬移

    """

    def __init__(self, length):
        self.items = [0 for _ in range(length)]
        self.head = 0
        self.tail = 0
        self.length = length

    def size(self):
        return self.tail - self.head

    def enqueue(self, item):
        if self.tail >= self.length:
            if self.head == 0:
                raise Exception("Full")
            # 进行数据搬移
            for i in range(self.head, self.tail):
                self.items[i - self.head] = self.items[i]
            # 移动完毕后重新更新head和tail
            self.tail = self.tail - self.head
            self.head = 0

        self.items[self.tail] = item
        self.tail += 1

    def dequeue(self):
        if self.head >= self.tail:
            raise Exception("Empty")
        data = self.items[self.head]
        self.head += 1
        return data


if __name__ == "__main__":
    q = Queue(10)
    for i in range(10):
        q.enqueue(i)

    print(q.dequeue())
    print(q.dequeue())

    q.enqueue(11)
    q.enqueue(12)

    res = []
    while True:
        try:
            res.append(q.dequeue())
        except Exception as e:
            print(e)
            break
    print(res)


"""
0
1
Empty
[2, 3, 4, 5, 6, 7, 8, 9, 11, 12]
"""

链式队列

# coding:utf-8

"""
基于链表实现的复杂度
"""


class Node(object):
    def __init__(self, data, next_=None):
        self.data = data
        self.next_ = next_


class Queue(object):
    def __init__(self):
        self.head = None
        self.tail = None
        self.length = 0

    def size(self):
        return self.length

    def enqueue(self, item):
        if self.head == None:
            self.head = Node(item)
            self.tail = self.head
        else:
            self.tail.next_ = Node(item)
            self.tail = self.tail.next_
        self.length += 1

    def dequeue(self):
        if self.head == None:
            raise Exception("Empty")
        data = self.head.data
        self.head = self.head.next_
        self.length -= 1
        return data


if __name__ == "__main__":
    q = Queue()
    for i in range(10):
        q.enqueue(i)

    res = []
    while True:
        try:
            res.append(q.dequeue())
        except Exception as e:
            print(e)
            break
    print(res)

循环队列

该类型队列可以避免移动元素的操作
技术图片
上图中队列大小是8. 判断队列满的条件是(tail + 1) % n = head

# coding:utf-8

"""
循环队列
"""


class QueueLoop(object):
    def __init__(self, length):
        self.items = [0 for _ in range(length)]
        self.head = 0
        self.tail = 0
        self.length = length + 1    # 循环队列会多用一位, 因为当tail指向最后一个空位置时认为已经满了

    def enqueue(self, item):
        if self.is_full():
            raise Exception("Full")
        self.items[self.tail] = item
        self.tail += 1

    def dequeue(self):
        if self.is_empty():
            raise Exception("Empty")
        data = self.items[self.head]
        self.head = self.head + 1
        return data

    def is_empty(self):
        if self.head == self.tail:
            return True
        else:
            return False

    def is_full(self):
        """
        当tail指向head的前一位的时候认为队列已满
        :return: 
        """
        if (self.tail + 1) % self.length == self.head:
            return True
        else:
            return False



if __name__ == "__main__":
    q = QueueLoop(10)

    for i in range(10):
        q.enqueue(i)

    res = []
    while True:
        try:
            res.append(q.dequeue())
        except Exception as e:
            print(e)
            break
    print(res)


"""
Empty
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

"""
    
"""
Empty
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

"""

技术图片

资料

  • <<大话数据结构>>-程杰
  • 数据结构和算法之美-王争

以上是关于数据结构和算法-列表的主要内容,如果未能解决你的问题,请参考以下文章

从搜索文档中查找最小片段的算法?

如何将列表视图中的数据从一个片段发送到另一个片段

如何从片段内的列表视图打开链接网址?

当我从用户获取数据并将其保存到 SQLite 数据库中时,我应该怎么做才能使列表视图在片段中工作

片段(Java) | 机试题+算法思路+考点+代码解析 2023

如何在片段中填充列表视图?