双向链表
在单链表的基础上,增加了一个链接,指向前一个节点(prev以及next两个链接)当当前节点为头节点时,prev指向空置,而next指向下一个节点。
双向链表的操作
is_empty() 链表是否为空
length() 链表长度
travel() 遍历链表
add(item) 链表头部添加
append(item) 链表尾部添加
insert(pos, item) 指定位置添加
remove(item) 删除节点
search(item) 查找节点是否存在
在python中实现
class Node(object):
def __init__(self,item):
self.elem = item #元素
self.next = None #下一个节点的指向
self.prev = None #上一个节点的指向
class DoubleLinkList(object):
def __init__(self,node=None):
self.__head = node
def is_empty(self):
return(self.__head == None)
def length(self):
# cur 游标 用来移动遍历节点
cur = self.__head
# count 计数
count = 0
while cur != None:
count += 1
cur = cur.next
return count
def travel(self):
cur = self.__head
while cur != None:
print(cur.elem,end=' ')
cur = cur.next
def add(self,item):
'''头部添加节点'''
node = Node(item)
node.next = self.__head #将新节点的下一个节点指向旧的头节点
self.__head = node #将头结点更新为新节点
node.next.prev = node #将下一个节点的prev指向新节点
'''
self.__head.prev = node
self.__head = node
与上两句效果一样
'''
def append(self,item):
node = Node(item)
if self.is_empty():
self.__head = node #如果链表为空 直接将头节点更新为新节点
else:
cur = self.__head #指针
while cur.next != None: #遍历节点 遍历到最后一个节点
cur = cur.next
cur.next = node #更新原链表next指向新节点
node.prev = cur #更新新节点的prev指向
def insert(self,pos,item):
''' :param pos: 从0开始
:param item:
:return:'''
if pos < 0:
self.add(item) #同单链表一样
elif pos > (self.length()-1): #如果插入位置是最后一个 和在尾部添加相同
self.append(item)
else: #正常情况下 不断地走 走到pos指向位置的前一个位置停下 跳出循环
cur = self.__head
count = 0
while count < (pos-1):
cur = cur.next
count += 1
#循环退出后 pre指向pos-1的位置
node = Node(item)
node.next = cur # 新节点下一节点指向pos位置上的节点
node.prev = cur.prev #新节点的前一个节点指向pos位置的前一个节点
cur.prev.next = node #更新cur.prev.next指向新节点
cur.prev = node #更新cur.prev指向新节点
'''
node.next = cur
node.prev = cur.prev
cur.prev = node
node.prev.next = node
与上四句话一样效果
'''
def remove(self,item):
cur = self.__head
while cur != None:
if cur.elem == item:
#先判断当前节点是否为头节点
#如果是头节点
if cur == self.__head:
self.__head = cur.next #头节点直接指向下一个节点
if cur.next != None: #不满足该条件证明只有一个节点 cur.next = None
#判断链表是否只有一个节点 有下一个节点才有cur.next
cur.next.prev = None #现在指针.next.prev指针指向空
else:
#打断cur前后的指向 将cur前一个节点next的指向 cur后一个节点
cur.prev.next = cur.next
#判断节点是否在尾部 不是尾部才有cur.next 尾部cur.next=None
if cur.next != None:
cur.next.prev = cur.prev
break #一定退出!!!
else:
cur = cur.next #正常遍历
def search(self,item):
cur = self.__head
while cur != None:
if cur.elem == item:
return True
else:
cur = cur.next
return False
单向循环链表
在单链表的基础上,将单链表尾部节点的指向头节点,形成一个循环
常见操作函数
is_empty() 判断链表是否为空
length() 返回链表的长度
travel() 遍历
add(item) 在头部添加一个节点
append(item) 在尾部添加一个节点
insert(pos, item) 在指定位置pos添加节点
remove(item) 删除一个节点
search(item) 查找节点是否存在
在Python中的操作:
class Node(object):
def __init__(self,elem):
self.elem = elem
self.next = None
class SingleCycleLinkList(object):
def __init__(self,node = None):
self.__head = node
if node:
node.next = node
def is_empty(self):
'''链表是否为空'''
return(self.__head == None) #判断头节点是否为空
def length(self):
# cur 游标 用来移动遍历节点
if self.is_empty():
return 0
cur = self.__head
# count 计数
count = 1 # 从1开始计数 因为从0开始计数会少1
while cur.next != self.__head:
count += 1
cur = cur.next #正常遍历
return count
def travel(self):
if self.is_empty():
return
cur = self.__head
while cur.next != self.__head:
print(cur.elem,end=' ')
cur = cur.next
#退出循环 cur指向为节点 但尾节点未打印
print(cur.elem,end=' ')
def add(self,item):
'''头部添加节点 相比其他链表 单向循环链表需要遍历走完整个链表 记住尾部节点 并指向新的头节点'''
node = Node(item)
if self.is_empty():#空链表时直接添加
self.__head = node
node.next = node
else:
cur = self.__head
while cur.next != self.__head: #正常遍历
cur = cur.next
#退出循环 cur指向尾节点
node.next = self.__head # 将新节点插在头节点前 也就是新节点.next指向头节点
self.__head = node #定义新的头节点
cur.next = self.__head 尾节点指向头节点
def append(self,item):
node = Node(item)
if self.is_empty():
self.__head = node
node.next = node
else:
cur = self.__head
while cur.next != self.__head: #遍历
cur = cur.next
cur.next = node #插入新节点 旧链表尾部节点.next指向新节点
node.next = self.__head #新节点.next指向头节点
def insert(self,pos,item):
'''
指定位置插入节点
:param pos: 从0开始
'''
if pos < 0:
self.add(item)
elif pos > (self.length()-1):
self.append(item)
else:
pre = self.__head
count = 0
while count < (pos-1):
pre = pre.next
count += 1
#循环退出后 pre指向pos-1的位置
node = Node(item)
node.next = pre.next
pre.next = node
def remove(self,item):
#pre和cur 两个游标差一个位置
pre = None
cur = self.__head
if self.is_empty():
return
while cur.next != self.__head:
if cur.elem == item:
#先判断当前节点是否为头节点
#如果是头节点
if cur == self.__head:
#头节点恰好是删除的 需要游标找到尾节点 将尾节点指向头节点的下一个节点
rear = self.__head
while rear.next != self.__head:#遍历 找到尾部节点
rear = rear.next
#退出循环找到尾部节点
self.__head = cur.next #打断原来链表头节点的指向 指向cur.next
rear.next = self.__head #更新尾部节点的指向 指向新的头节点
else:
pre.next = cur.next #中间节点打断无需考虑尾部节点的指向
return
else: #遍历
pre = cur
cur = cur.next
#退出循环 cur指向尾节点
if cur.elem == item:
if cur == self.__head:
#链表只有一个节点 游标没有移动
self.__head = None #直接删除
else:
pre.next = cur.next #打断链接
#pre.next = self.__head
def search(self,item):
cur = self.__head
while cur != self.__head:
if cur.elem == item:
return True #找到则返回
else:#没找到继续遍历
cur = cur.next
if cur.elem == item: #补充尾部节点的情况
return True
return False
栈
栈又称为堆栈,是一种容器,用来存储线性数据,按照先进后出的规则运行。
在Python中的操作
class Stack(object):
def __init__(self):
self.__list = [] #初始化空列表
def push(self,item):
'''添加要给新的元素item'''
self.__list.append(item)
# self.__list.insert(0,item) 头部时间复杂度O(n) 尾部时间复杂度为O(1)
def pop(self):
'''移除栈顶元素并弹出'''
return self.__list.pop()
def peek(self):
'''返回栈顶元素'''
if self.__list:
return self.__list[-1]
else:
return None
def is_empty(self):
return self.__list == []
def size(self):
return len(self.__list)
队列
队列是允许在一段进行插入操作 而在另一端进行删除操作的线性表
按照先进先出的规律进行运行
在Python中的操作
class Queue(object):
'''Queue() 创建一个空的队列
enqueue(item) 往队列中添加一个item元素
dequeue() 从队列头部删除一个元素
is_empty() 判断一个队列是否为空
size() 返回队列的大小'''
def __init__(self):#初始化空列表
self.__list = []
def enqueue(self,item):
self.__list.append(item)
#self.__list.insert(0,item) 对应不一样的dequue操作
def dequeue(self):
'''从头部删除一个元素并返回'''
return self.__list.pop(0)
def is_empty(self):
return self.__list ==[]
def size(self):
return len(self.__list)
双端队列
可以选择从头或者尾 两端进行数据操作
在Python中的操作
class Deque(object):
'''双端队列
Deque() 创建一个空的双端队列
add_front(item) 从队头加入一个item元素
add_rear(item) 从队尾加入一个item元素
remove_front() 从队头删除一个item元素
remove_rear() 从队尾删除一个item元素
is_empty() 判断双端队列是否为空
size() 返回队列的大小'''
def __init__(self):
self.__list = []
def add_front(self, item):
'''从头部添加数据'''
self.__list.insert(0,item)
def add_rear(self, item):
'''从尾部添加数据'''
self.__list.append(item)
def pop_front(self):
'''从头部删除一个元素并返回'''
return self.__list.pop(0)
def pop_rear(self):
'''从尾部删除一个元素并返回'''
return self.__list.pop()
def is_empty(self):
return self.__list == []
def size(self):
return len(self.__list)