一、单链表
- 概念
单向链表也叫单链表,是链表中最简单的⼀种形式,它的每个节点包含两个 域,⼀个信息域(元素域)和⼀个链接域。这个链接指向链表中的下⼀个节 点,⽽最后⼀个节点的链接域则指向⼀个空值。
-说明
- 表元素域elem⽤来存放具体的数据。
- 链接域next⽤来存放下⼀个节点的位置(python中的标识)
- 变量p指向链表的头节点(⾸节点)的位置,从p出发能找到表中的任意节点。
- python实现
'''单链表节点结构'''
class SingleNode():
def __init__(self,item):
self.item = item
self.next = None
#is_empty() 链表是否为空
#length() 链表⻓度
#travel() 遍历整个链表
#add(item) 链表头部添加元素
#append(item) 链表尾部添加元素
#insert(pos, item) 指定位置添加元素
#remove(item) 删除节点
'''单链表结构'''
class SingleLinkList():
def __init__(self):
'''定义链表的头节点'''
self.head = None
def is_empty(self):
'''判断链表是否为空'''
return self.head == None
def length(self):
'''获取链表的长度'''
count = 0
cur = self.head # 游标
while cur != None:
cur = cur.next
count += 1
return count
def travel(self):
'''遍历整个链表'''
cur = self.head
while cur != None:
print(cur.item)
cur = cur.next
def add(self,item):
'''链表头部添加元素'''
node = SingleNode(item) # 定义要插入的节点
node.next = self.head
self.head = node
def append(self,item):
'''链表尾部添加元素'''
node = SingleNode(item)
cur = self.head
if cur== None: # 空链表
self.head = node
else: # 非空节点
while cur.next != None:
cur = cur.next
# 退出循环后cur指向链表最后一个节点
cur.next = node
def insert(self,item,pos):
'''向链表指定位置添加元素'''
node = SingleNode(item)
if pos <= 0: # 表头添加
self.add(item)
elif pos >= self.length()-1: # 表尾添加
self.append(item)
else: # 其他位置添加
cur = self.head
count = 0
while count <= pos - 1:
cur = cur.next
count += 1
# 退出循环时cur指向插入位置的前一位置
node.next = cur.next
cur.next = node
def remove(self,item):
'''删除链表节点'''
node = SingleNode(item)
cur = self.head
while cur.item != item:
pre = cur
cur = cur.next
# 退出循环后cur指向要删除的节点,pre指向要删除节点的前一节点
pre.next = cur.next
二、双向链表
- 概念
- 双向链表是⼀种更复杂的链表,称作“双向链表”或“双⾯链表”。
- 每个节点有两个链接:⼀个指向前⼀个节点,当此节点为第⼀个节点时,指向空值;
- 另⼀个指向下⼀个 节点,当此节点为最后⼀个节点时,指向空值。
- python实现
'''双链表节点结构'''
class DoubleLinkNode():
def __init__(self,item):
self.pre = None
self.item = item
self.next = None
#is_empty() 链表是否为空
#length() 链表⻓度
#add(item) 链表头部添加
#append(item) 链表尾部添加
#insert(pos, item) 指定位置添加
#remove(item) 删除节点
#search(item) 查找节点是否存在
'''双链表结构'''
class DoubleLink():
def __init__(self):
self.head = None
def is_empty(self):
'''判断链表是否为空'''
return self.head == None
def length(self):
'''获取链表长度'''
cur = self.head
count = 0
while cur != None:
cur = cur.next
count += 1
return count
def travel(self):
'''遍历链表'''
cur = self.head
while cur != None:
print(cur.item)
cur = cur.next
def add(self,item):
'''链表头部添加'''
node = DoubleLinkNode(item)
node.next = self.head
self.head = node
node.pre = self.head
def append(self,item):
'''链表尾部添加节点'''
node = DoubleLinkNode(item)
cur = self.head
pre = None
while cur != None:
pre = cur
cur = cur.next
# 退出循环时cur指向None,pre指向倒数第一个节点
pre.next = node
node.pre = pre
def insert(self,pos,item):
'''链表指定位置添加'''
node = DoubleLinkNode(item)
if pos <= 0:
self.add(item)
elif pos > self.length() - 1:
self.append(item)
else:
count = 0
pre = None
cur = self.head
while count < pos :
pre = cur
cur = cur.next
count += 1
#退出循环时cur指向该插入得位置,pre指向前一位置
pre.next = node
node.pre = pre
node.next = cur
cur.pre = node
def remove(self,item):
'''删除节点'''
cur = self.head
pre = None
while cur.item != item:
pre = cur
cur = cur.next
# 退出循环后cur指向需要删除的节点,pre指向插入位置的前一位置
pre.next = cur.next
cur.pre = pre
def search(self,item):
'''查找链表中是否存在此节点'''
cur = self.head0
while cur != None:
if cur.item == item:
return True
cur = cur.next
return False
三、栈
-
概念
栈(stack),有些地⽅称为堆栈,是⼀种容器,可存⼊数据元素、访问元 素、删除元素, -
特点
- 只能允许在容器的⼀端(称为栈顶端指标,英 语:top)进⾏加⼊数据(英语:push)和输出数据(英语:pop)的运算。
- 栈数据结构只允许在⼀端进⾏操作,因⽽按照后进先出(LIFO, Last In First Out)的原理运作
- python实现顺序栈
栈可以⽤顺序表实现,也可以⽤链表实现。
# push(item) 添加⼀个新的元素item到栈顶
# pop() 弹出栈顶元素
# peek() 返回栈顶元素
# is_empty() 判断栈是否为空
# size() 返回栈的元素个数
class Stack():
def __init__(self):
'''创建空栈'''
self.items = []
def push(self,item):
'''向栈顶添加元素'''
self.items.append(item)
def pop(self):
'''弹出栈顶元素'''
return self.items.pop()
def peek(self):
'''返回栈顶元素'''
print(self.items[-1])
def is_empty(self):
'''判断栈是否为空'''
return self.items == []
def size(self):
'''返回栈得元素个数'''
return len(self.items)
四、队列
- 概念
队列(queue)是只允许在⼀端进⾏插⼊操作,⽽在另⼀端进⾏删除操作的线性表。 - 特点
- 队列是⼀种先进先出的(First In First Out)的线性表,简称FIFO。
- 允许插⼊ 的⼀端为队尾,允许删除的⼀端为队头。队列不允许在中间部位进⾏操作!
- python实现
队列可以⽤顺序表实现,也可以⽤链表实现。
#enqueue(item) 往队列中添加⼀个item元素
#dequeue() 从队列头部删除⼀个元素
#is_empty() 判断⼀个队列是否为空
#size() 返回队列的⼤⼩
class Queue():
def __init__(self):
'''空队列'''
self.items = []
def enqueue(self,item):
'''从列表尾部添加元素'''
self.items.insert(0,item)
def dequeue(self):
'''从列表尾部删除元素'''
return self.items.pop()
def is_empty(self):
'''判断队列是否为空'''
return self.items == []
def size(self):
'''返回队列大小'''
return len(self.items)
五、双端队列
-
概念
双端队列(deque,全名double-ended queue),是⼀种具有队列和栈的性 质的数据结构 -
特点
双端队列中的元素可以从两端弹出,其限定插⼊和删除操作在表的两端进⾏。双端队列可以在队列任意⼀端⼊队和出队 -
python实现
队列可以⽤顺序表实现,也可以⽤链表实现。
# Deque() 创建⼀个空的双端队列
# add_front(item) 从队头加⼊⼀个item元素
# add_rear(item) 从队尾加⼊⼀个item元素
# remove_front() 从队头删除⼀个item元素
# remove_rear() 从队尾删除⼀个item元素
# is_empty() 判断双端队列是否为空
# size() 返回队列的⼤⼩
class Deque():
def __init__(self):
'''空双端队列'''
self.items = []
def add_front(self,item):
'''从队头加入item元素'''
self.items.insert(0,item)
def add_rear(self,item):
'''从队尾加入item元素'''
self.items.append(item)
def remove_front(self):
'''从队头删除item元素'''
return self.items.pop(0)
def remove_rear(self):
'''从队尾删除item元素'''
return self.items.pop()
def is_empty(self):
'''判断队列是否为空'''
return self.items == []
def size(self):
'''返回队列大小'''
return len(self.items)
六、顺序表和链表操作复杂度比较
- 说明
- 顺序表中元素的物理存储单元是连续的,元素位置可直接通过计算得到,所以复杂度为O(1)
- 链表中元素的物理存储单元是非连续的,访问元素必须从链表第一个元素开始访问,所以复杂度为O(n)
- 顺序表中在头部插入/删除数据,如果是保序插入/删除,所有的元素均向后移动一次,所有时间复杂度是O(n)
- 链表中在头部插入/删除数据,只需查找到头元素,然后再进行添加/删除,所有时间复杂度是O(1)
- 顺序表中在尾部插入/删除数据,只需先查找到尾部元素,然后再进行插入/删除操作,顺序表中查找元素时间复杂度为O(1),因此在顺序表尾部插入/删除数据时复杂度为O(1)
- 链表中在尾部插入/删除数据,需从头到尾查找到尾部元素,时间复杂度为O(n),然后再进行插入/删除操作,因此在链表尾部插入/删除数据时复杂度为O(1)
- 顺序表中在中部插入/删除数据,需先查找到中部元素,然后再进行插入/删除操作,顺序表中查找元素时间复杂度为O(1),因此在顺序表中部插入/删除数据时复杂度为O(1)
- 链表中在中间插入/删除数据,需先查找到中间元素,然后再进行插入/删除操作,链表表中查找元素时间复杂度为O(n),因此在链表中部插入/删除数据时复杂度为O(n)