一、 栈的原理
列表构建栈,那么栈顶(top)对应着列表表尾,栈底(bottom)对应列表表头
栈只能在栈顶进行操作:入栈/进栈/压栈/push
出栈/pop
栈的性质:后进先出
1.1 python的代码实现:
class Stack:
def __init__(self):
self.items = []
def push(self, item):
"""将元素压入栈顶"""
self.items.append(item)
def pop(self):
"""弹出栈顶元素"""
if not self.is_empty():
return self.items.pop()
else:
return None
def is_empty(self):
"""检查栈是否为空"""
return len(self.items) == 0
def peek(self):
"""查看栈顶元素,但不弹出"""
if not self.is_empty():
return self.items[-1]
else:
return None
def size(self):
"""返回栈的大小"""
return len(self.items)
stack = Stack()
stack.push(1)
stack.push(2)
stack.push(3)
print("Stack size:", stack.size()) # Output: 3
print("Top element:", stack.peek()) # Output: 3
while not stack.is_empty():
print("Popped:", stack.pop())
# Output:
# Popped: 3
# Popped: 2
# Popped: 1
二、队列
队列(Queue)是一种遵循先进先出(FIFO)原则的数据结构,即最先进入的元素首先被访问。在队列中,元素的插入(入队)操作发生在队列的末尾,而删除(出队)操作发生在队列的前端。
以下是重新生成的队列(Queue)类的实现代码:
class Queue:
def __init__(self):
self.items = []
def enqueue(self, item):
"""将元素加入队列尾部"""
self.items.append(item)
def dequeue(self):
"""从队列前端弹出元素"""
if not self.is_empty():
return self.items.pop(0)
else:
return None
def is_empty(self):
"""检查队列是否为空"""
return len(self.items) == 0
def peek(self):
"""查看队列前端元素,但不弹出"""
if not self.is_empty():
return self.items[0]
else:
return None
def size(self):
"""返回队列的大小"""
return len(self.items)
queue = Queue()
queue.enqueue(1)
queue.enqueue(2)
queue.enqueue(3)
print("Queue size:", queue.size()) # Output: 3
print("Front element:", queue.peek()) # Output: 1
while not queue.is_empty():
print("Dequeued:", queue.dequeue())
# Output:
# Dequeued: 1
# Dequeued: 2
# Dequeued: 3
三:链表
3.1.定义:链表(Linked list)是一种常见的基础数据结构,是一种线性表,在每一个节点(数据存储单元)里存放下一个节点的位置信息
3.2.优点:顺序表的构建需要预知数据大小来申请连续存储空间,扩充时需要进行数据迁移,使用不灵活,链表充分利用计算机内存空间,实现灵活内存动态管理
3.1 单向链表
(1)表元素域elem用来存放具体的数据
(2)链接域next用来存放下一个节点的位置
(3)变量p指向链表的头节点(首节点)的位置,从p出发能找到表中的任意节#定义节点 class Node(object): def __init__(self,elem): self.elem=elem self.next=None #构造单向链表 class SingleLinkedList: #判断链表是否为空:_head指向None,则为空 def is_empty(self): ''' if self._head==None: print("True") else: print("False") ''' return self._head==None #单向链表初始化 def __init__(self,node=None): #判断node是否为空 if node!=None: headNode=Node(node) self._head=headNode else: self._head=node #计算链表长度 def length(self): count=0 curNode=self._head while curNode!=None: count+=1 curNode=curNode.next return count #遍历链表 def travel(self): curNode=self._head while curNode!=None: print(curNode.elem,end='\t') curNode=curNode.next print(" ") #在头部添加元素 def add(self,item): #将传入的值构造成节点 node=Node(item) #将新节点的链接域next指向头节点 node.next=self._head #将链表的头_head指向新节点 self._head=node #在尾部添加元素 def append(self,item): #将传入的值构造成节点 node=Node(item) if self.is_empty(): #单链表为空 self._head=node else: #单链表不为空 curNode=self._head while curNode.next!=None: curNode=curNode.next #修改节点,最后一个节点的next指向node curNode.next=node #在指定位置添加元素 def insert(self,pos,item): #如果pos<=0,默认插入到头部 if pos<=0: self.add(item) #如果pos>链表长度,直接在尾部追加 elif pos>(self.length()-1): self.append(item) else: #构造节点 node=Node(item) count=0 preNode=self._head while count<(pos-1): #查找前一个节点 count+=1 preNode=preNode.next #修改指向 #将前一个节点的next指向插入节点 node.next=preNode.next #将插入位置的前一个节点next指向新节点 preNode.next=node #查找节点是否存在 def search(self,item): curNode=self._head while curNode!=None: if curNode.elem==item: return True curNode=curNode.next return False #删除节点 def remove(self,item): curNode=self._head preNode=None while curNode!=None: if curNode.elem==item: #判断是否是头节点 if preNode==None:#是头节点 self._head=curNode.next else: #删除 preNode.next=curNode.next break else: preNode=curNode curNode=curNode.next if __name__=="__main__": #初始化元素值为10单向链表 singleLinkedList=SingleLinkedList(30) print("是否为空链表:",singleLinkedList.is_empty()) print("链表长度为:",singleLinkedList.length()) print("----遍历链表----") singleLinkedList.travel() print("-----查找-----",singleLinkedList.search(30)) print("-----头部插入-----") singleLinkedList.add(1) singleLinkedList.add(2) singleLinkedList.add(3) singleLinkedList.travel() print("-----尾部追加-----") singleLinkedList.append(10) singleLinkedList.append(20) singleLinkedList.travel() print("-----链表长度-----",singleLinkedList.length()) print("-----指定位置插入-----") singleLinkedList.insert(-1,100) singleLinkedList.travel() print("-----删除节点-----") singleLinkedList.remove(100) singleLinkedList.travel()
是否为空链表: False
链表长度为: 1
----遍历链表----
30
-----查找----- True
-----头部插入-----
3 2 1 30
-----尾部追加-----
3 2 1 30 10 20
-----链表长度----- 1
-----指定位置插入-----
100 3 2 1 30 10 20
-----删除节点-----
3 2 1 30 10 20
3.2双向链表
1.双向链表(双面链表)是一种更复杂的链表。每个节点有两个链接:一个指向前一个节点,当此节点为第一个节点时,指向空值,而另一个指向下一个节点,当此节点为最后一个节点时,指向空值。
class Node:
def __init__(self,elem):
self.elem=elem
self.next=None #下一个节点
self.prev=None #前一个节点
class DoubleLinkedList:
# 双向链表初始化
def __init__(self, node=None):
# 判断node是否为空
if node != None:
headNode=Node(node)
self._head=headNode
else:
self._head=node
def is_empty(self):
'''
if self._head==None:
print("True")
else:
print("False")
'''
return self._head==None
#计算链表长度
def length(self):
count=0
curNode=self._head
while curNode!=None:
count+=1
curNode=curNode.next
return count
#遍历链表
def travel(self):
curNode=self._head
while curNode!=None:
print(curNode.elem,end='\t')
curNode=curNode.next
print(" ")
#在头部添加元素
def add(self,item):
#判断是否空链表
node = Node(item)
if self.is_empty():
self._head=node
else:
#将传入的值构造成节点
node=Node(item)
#将新节点的链接域next指向头节点
node.next=self._head
#将_head的头节点的prev指向node
self._head.prev=node
#将链表的头_head指向新节点
self._head=node
#在尾部追加元素
def append(self,item):
#将传入的值构造成节点
node=Node(item)
if self.is_empty(): #双向链表为空
self._head=node
else: #双向链表不为空
curNode=self._head
while curNode.next!=None:
curNode=curNode.next
#修改节点,最后一个节点的next指向node
curNode.next=node
#将node节点的前驱指向当前节点
node.prev=curNode
#在指定位置添加元素
def insert(self,pos,item):
#如果pos<=0,默认插入到头部
if pos<=0:
self.add(item)
#如果pos>链表长度,直接在尾部追加
elif pos>(self.length()-1):
self.append(item)
else:
#构造节点
node=Node(item)
count=0
curNode=self._head
while count<(pos-1): #查找前一个节点
count+=1
curNode=curNode.next
#修改指向
#node节点前驱指向当前节点
node.prev=curNode
#node节点的next指向当前节点的下一个节点
node.next=curNode.next
#当前节点的下一个节点的前驱指向node节点
curNode.next.prev=node
#当前节点的下一个节点指向node节点
curNode.next=node
#查找节点是否存在
def search(self,item):
curNode=self._head
while curNode!=None:
if curNode.elem==item:
return True
curNode=curNode.next
return False
#删除节点
def remove(self,item):
curNode=self._head
while curNode!=None:
if curNode.elem==item:
#判断是否是头节点
if curNode==self._head:#是头节点
self._head=curNode.next
#判断当前节点是否只有一个节点
if curNode.next:
curNode.next.prev==None
else:
#删除
curNode.prev.next=curNode.next
#判断当前节点是否是最后一个节点,若是,不需要移动下一个
if curNode.next:
curNode.next.prev=curNode.prev
break
else:
curNode=curNode.next
if __name__=="__main__":
doubleLinkedList=DoubleLinkedList()
print("-----头部添加-----")
doubleLinkedList.add(11)
doubleLinkedList.add(22)
doubleLinkedList.add(33)
doubleLinkedList.travel()
print("-----尾部追加-----")
doubleLinkedList.append(44)
doubleLinkedList.travel()
print("指定位置插入")
doubleLinkedList.insert(3,100)
doubleLinkedList.travel()
print("-----删除元素-----")
doubleLinkedList.remove(33)
doubleLinkedList.travel()
-----头部添加-----
33 22 11
-----尾部追加-----
33 22 11 44
指定位置插入
33 22 11 44 100
-----删除元素-----
22 11 44 100
————————————————
参考文献:
【Python——链表】_python 链表-优快云博客
Python的常见数据结构 - 知乎 (zhihu.com)