1、Python 基本数据结构

来源:互联网 发布:上瘾网络剧上海见面会 编辑:程序博客网 时间:2024/05/22 06:49

一、线性数据结构

1. 线性数据结构的特点

  • 数据项之间只存在先后的次序关系,新的数据项加入到数据集中时,只会加入到原有某个数据项之前或之后
  • 线性结构总有两端:左右端、前后端、顶端底端等,但两端的称呼并不是关键,不同线性结构的关键区别在于数据项增减的方式
  • 有的结构只允许数据项从一端添加,而有的结构则允许数据项从两端移除

2. 线性数据结构分类

  • 栈(stack)
  • 队列(queue)
  • 双端队列(deque)
  • 链表(LinkedList)

二、栈(stack)

1. 栈的特点

  • 栈是一种有次序的数据项集合,在栈中,数据项的加入和移除都仅发
    生在栈顶
  • 后进先出:Last in First out(LIFO),eg: word 中的 undo
  • 反转次序

2. 使用列表来模拟栈

  • 假设栈要实现如下功能:
    这里写图片描述

  • 代码实践

# 选用 List 的尾端(index=-1)作为栈顶,此时push/pop的复杂度为O(1)# 若选用 List 的首端(index=0)作为栈顶,其push/pop的复杂度为O(n),因为要用pop(0),insert(0,item)等来模拟出栈和入栈class Stack:     """使用 list 来模拟栈"""     def __init__(self):         self.items = []     def isEmpty(self):         return self.items == []      def push(self, item):         self.items.append(item)     def pop(self):         if not self.isEmpty():             return self.items.pop()      def peek(self):         if not self.isEmpty():             return self.items[len(self.items)-1]     def size(self):         return len(self.items) s = Stack()s.isEmpty() = Trues.push(4)s.push('dog')s.peek() = 'dog's.size() = 2s.pop() = 'dog's.pop() = 4

三、队列(queue)

1. 队列的特点

  • 队列是一种有次序的数据集合,新数据项的添加总发生在尾端(rear),而现存数据项的移除总发生在首端(front)
  • 先进先出:First in First out(FIFO),eg: 打印队列
  • 队列仅有一个入口和一个出口,不允许数据项直接插入队中,也不允许从中
    间移除数据项
    这里写图片描述

2. 使用列表来模拟队列

  • 假设队列要实现如下功能:
    这里写图片描述
  • 代码实践
# 将 list 的首端作为队列的尾端,list 的末端作为队列的首端class Queue:    """使用 list 来模拟队列"""    def __init__(self):        self.items = []    def isEmpty(self):        return self.items == []    def enqueue(self, item):        self.items.insert(0, item)    def dequeue(self):        if not self.isEmpty():            return self.items.pop()    def size(self):        return len(self.items)q=Queue()q.enqueue(4) = [4]q.enqueue('dog') = ['dog', 4]q.size() = 2q.isEmpty() = Falseq.dequeue() # 4 出队,list 中还剩['dog']

四、双端队列(deque)

1. 双端队列的特点

  • 双端队列是一种有次序的数据集,其首端和尾端都可以加入数据和移除数据
  • 某种意义上说,双端队列集成了栈和队列的能力,但双端队列并不具有内在的LIFO或者FIFO特性,如果用双端队列来模拟栈或队列,需要由使用者自行维护操作的一致性
    这里写图片描述

2. 使用列表来模拟双端队列

  • 假设栈要实现如下功能:
    这里写图片描述
# 将 list 的首端作为双端队列的尾端,list 的末端作为双端队列的首端class Deque:    """使用 list 来模拟双端队列"""    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):        if not self.isEmpty():            return self.items.pop()    def removeRear(self):        if not self.isEmpty():            return self.items.pop(0)    def size(self):        return len(self.items)d=Deque()d.addRear(4) = [4]d.addRear('dog') = ['dog', 4]d.addFront('cat') = ['dog', 4, 'cat']d.size() = 3d.removeRear() # 移除'dog', 还剩[4, 'cat']d.removeFront() # 移除'cat', 还剩[4]

五、链表(LinkedList)

1. 链表简介

  • 链表是实现了数据之间保持逻辑顺序(通过引用实现),但存储空间不必按顺序的方法
  • 链表中的基本要素:
    • 节点:每一个节点有两个域,左边部份叫值域,用于存放用户数据;右边叫指针域,一般是存储着到下一个元素的指针(python 中使用引用来实现)
    • head 节点:没有值域,只有指针域且永远指向第一个节点
    • tail 节点:有值域,有指针域但永远指向 None
  • 使用链表的好处
    • 插入删除速度很快,不用对整个链表进行调整
    • 能够动态的进行存储分配
  • 移除链表中某元素示例
    这里写图片描述

2. 使用类来模拟链表(待扩展…)

  • 假设链表要实现如下功能:
    这里写图片描述
  • 代码实践
# 节点类class Node:    def __init__(self, init_data):        self.data = init_data        self.next = None    def get_data(self):        return self.data    def get_next(self):        return self.next    def set_data(self, new_data):        self.data = new_data    def set_next(self, new_next):        self.next = new_next# 链表类class LinkedList:    def __init__(self):        self.head = None    def is_empty(self):        return self.head == None    # 从链表头插入对象     def add(self,item):        temp = Node(item)        temp.set_next(self.head)  # 将链表头指向的下一个对象的地址赋给待插入对象        self.head = temp          # 将待插入对象的地址赋给链表头    # 遍历链表,取得其长度    def size(self):        current = self.head        count = 0        while current != None:            count = count + 1            current = current.get_next()        return count    # 判断某元素是否在链表中    def search(self,item):        current = self.head        found = False        while current != None and not found:            if current.get_data() == item:                found = True            else:                current = current.get_next()        return found    # 移除链表中的某个元素    def remove(self,item):        current = self.head        previous = None        found = False        while not found:            if current.get_data() == item:                found = True            else:                previous = current                current = current.get_next()        if previous == None:              self.head = current.get_next()        else:            previous.set_next(current.get_next())

六、参考资料

1、北大数据结构与算法

原创粉丝点击