一,线性数据结构

1.线性数据结构的特点

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

2. 线性数据结构分类

 

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

二、栈(stack)

1. 栈的特点

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

2. 使用列表来模拟

  • 假设栈要实现如下功能:

python 数据结构 栈 python版数据结构_数据项

  • 代码实现
# 选用 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() = True
s.push(4)
s.push('dog')
s.peek() = 'dog'
s.size() = 2
s.pop() = 'dog'
s.pop() = 4

 三、队列(queue)
1. 队列的特点

队列是一种有次序的数据集合,新数据项的添加总发生在尾端(rear),而现存数据项的移除总发生在首端(front)

先进先出:First in First out(FIFO),eg: 打印队列

队列仅有一个入口和一个出口,不允许数据项直接插入队中,也不允许从中 

间移除数据项 

 

python 数据结构 栈 python版数据结构_数据结构_02

 

2. 使用列表来模拟队列

  • 假设队列要实现如下功能: 

python 数据结构 栈 python版数据结构_数据项_03

  • 代码实践
# 将 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() = 3
d.removeRear() # 移除'dog', 还剩[4, 'cat']
d.removeFront() # 移除'cat', 还剩[4]

五、链表(LinkedList)

1. 链表简介

链表是实现了数据之间保持逻辑顺序(通过引用实现),但存储空间不必按顺序的方法

  • 链表中的基本要素: 
  • 节点:每一个节点有两个域,左边部份叫值域,用于存放用户数据;右边叫指针域,一般是存储着到下一个元素的指针(python 中使用引用来实现)
  • head 节点:没有值域,只有指针域且永远指向第一个节点
  • tail 节点:有值域,有指针域但永远指向 None
  • 使用链表的好处 
  • 插入删除速度很快,不用对整个链表进行调整
  • 能够动态的进行存储分配
  • 移除链表中某元素示例 

 

python 数据结构 栈 python版数据结构_数据项_04

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

  • 假设链表要实现如下功能: 

python 数据结构 栈 python版数据结构_数据项_05

  • 代码实践
# 节点类
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、北大数据结构与算法