数据结构与算法–(链表,栈,队列)
文章目录
链表
定义
链表:是一种常见的数据结构,是一种线性表。不像顺序表那样连续存储数据,而是在每个节点(数据存储单元)里存放下一个节点的位置信息(地址)。
单向链表
单向链表也叫单链表,是链表中最简单的一种形式,它的每个节点包含两个域,一个信息域(元素域)和一个链接域。这个链接指向链表中的下一个节点,而最后一个节点的链接域则指向一个空值。
功能:
1.头部添加元素
def add(self,item):
node = Node(item)
# 将新节点的链接域next指向头结点
node.next=self.__head
#将链表头__head指向新节点
self.__head = node
2.尾部添加元素
#尾部追加
def append(self,item):
node = Node(item)
curNode = self.__head
#链表为空和不为空的情况
if self.is_empty():
self.__head = node
else:
while curNode.next !=None:
curNode = curNode.next
curNode.next = node
3.指定位置添加元素
#指定位置添加
def insert(self,post,item):
#如果post插入位置小于等于0,属于头部插入
if (post-1)<=0:
self.add(item)
# 如果post插入位置大于等于链表长度,属于尾部插入
elif post>=self.length():
self.append(item)
#正常插入
else:
count = 0
preNode = self.__head
node = Node(item)
while count<(post-1):
count += 1
preNode = preNode.next
node.next=preNode.next
preNode.next = node
4.删除节点
#删除节点
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
5.查找节点是否存在
#查找节点是否存在
def search(self,item):
curNode = self.__head
while curNode != None:
if curNode.elem==item:
return True
curNode = curNode.next
return False
6.判断链表是否为空
#判断当前链表是否为空
def is_empty(self):
return self.__head == None
7.当前链表的长度
#当前链表的长度
def length(self):
count = 0
curNode = self.__head
while curNode != None:
count += 1
curNode = curNode.next
return count
8.遍历链表
#遍历
def travel(self):
curNode = self.__head
while curNode != None:
print(curNode.elem,end='\t')
curNode = curNode.next
全部代码粘贴
class Node(object):
def __init__(self,elem):
#elem:数据元素
self.elem=elem
#next:下一个节点的链接域
self.next=None
#构建单向链表类
class SingleLinkList:
#初始化方法
def __init__(self,node=None):
if node!=None:
headNode = Node(node)
self.__head=headNode
else:
self.__head=node
# print(self.__head)
#在头部添加元素
def add(self,item):
node = Node(item)
# 将新节点的链接域next指向头结点
node.next=self.__head
#将链表头__head指向新节点
self.__head = node
#尾部追加
def append(self,item):
node = Node(item)
curNode = self.__head
#链表为空和不为空的情况
if self.is_empty():
self.__head = node
else:
while curNode.next !=None:
curNode = curNode.next
curNode.next = node
#指定位置添加
def insert(self,post,item):
#如果post插入位置小于等于0,属于头部插入
if (post-1)<=0:
self.add(item)
# 如果post插入位置大于等于链表长度,属于尾部插入
elif post>=self.length():
self.append(item)
#正常插入
else:
count = 0
preNode = self.__head
node = Node(item)
while count<(post-1):
count += 1
preNode = preNode.next
node.next=preNode.next
preNode.next = node
#删除节点
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
#查找节点是否存在
def search(self,item):
curNode = self.__head
while curNode != None:
if curNode.elem==item:
return True
curNode = curNode.next
return False
#判断当前链表是否为空
def is_empty(self):
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
if __name__ == '__main__':
singleLinkList=SingleLinkList()
# print('链表长度:',singleLinkList.length())
# print('链表是否为空:',singleLinkList.is_empty())
# print('遍历链表:', end=' ')
# singleLinkList.travel()
# print('查找节点是否存在:', singleLinkList.search(20))
# singleLinkList.add(1)
# singleLinkList.add(2)
# singleLinkList.add(3)
singleLinkList.append(1)
singleLinkList.append(2)
singleLinkList.append(3)
singleLinkList.insert(10,4)
singleLinkList.remove(4)
singleLinkList.remove(1)
print('遍历链表:', end=' ')
singleLinkList.travel()
循环链表
在链表中,使链表的尾部节点的‘next’指针指向链表的头部。
轮转调度:在这个调度程序中,以循环的方式迭代的遍历一个元素的集合,通过执行一个给定的动作为集合中的每个元素进行服务。
循环链表实现队列
class CircularQueue:
class _Node:
'''Lightweight,nonpublic class for storing a singly linked node.'''
__slots__ = '_element','_next'
def __init__(self,element,next):
self._element = element
self._next = next
def __init__(self):
'''create an empty queue'''
self._tail = None
self._size = 0
# queque length
def __len__(self):
return self._size
# queue is empty?
def is_empty(self):
'''return true if the queue is empty'''
return self._size == 0
def first(self):
'''return(but not remove) the element at the front of the queue'''
if self.is_empty():
raise TypeError("Queue is Empty!")
head = self._tail._next
return head._element
def dequeue(self):
'''remove and return the first element of thr queue'''
if self.is_empty():
raise TypeError('the Queue is empty!')
oldhead = self._tail._next
if self._size == 1:
self._tail._next = None
else:
self._tail._next = oldhead._next
return oldhead._element
def enqueue(self,item):
'''add an element to the back of queue'''
newest = self._Node(item,None)
if self.is_empty():
newest._next = newest
else:
newest._next = self._tail._next
self._tail._next = newest
self._tail = newest
self._size += 1
def rotate(self):
'''rotate front element to the back of the queue'''
if self._size >0:
self._tail = self._tail._next
def travel(self):
head = self._tail._next
print(head._element,end=' ')
head = head._next
while head is not self._tail._next:
print(head._element,end=' ')
head = head._next
print('')
if __name__ == '__main__':
circularQueue = CircularQueue()
circularQueue.enqueue(1)
circularQueue.enqueue(2)
circularQueue.enqueue(2)
circularQueue.travel()
print(circularQueue.dequeue())
circularQueue.travel()
双向链表
每个节点有两个链接:一个指向前一个节点(当此节点为第一个节点时,指向空值);另一个节点指向下一个节点(当此节点为最后一个节点时,指向空值)
功能:
1.头部添加元素
#在头部添加元素
def add(self,item):
node = Node(item)
#判断是否是空列表
if self.is_empty():
self.__head = node
else:
# 将新节点的链接域next指向头结点
node.next=self.__head
#将__head 的头节点的prev指向node
self.__head.prev = node
#将链表头__head指向新节点
self.__head = node
2.尾部添加元素
#尾部追加
def append(self,item):
node = Node(item)
curNode = self.__head
#链表为空和不为空的情况
if self.is_empty():
self.__head = node
else:
while curNode.next !=None:
curNode = curNode.next
curNode.next = node
#将node节点的前驱指向当前节点
node.prev = curNode
3.指定位置添加元素
#指定位置添加
def insert(self,post,item):
#如果post插入位置小于等于0,属于头部插入
if (post-1)<=0:
self.add(item)
# 如果post插入位置大于等于链表长度,属于尾部插入
elif post>=self.length():
self.append(item)
#正常插入
else:
count = 0
preNode = self.__head
node = Node(item)
while count<(post-1):
count += 1
preNode = preNode.next
node.next=preNode.next
node.prev = preNode
preNode.next.prev = node
preNode.next = node
4.删除节点
#删除节点
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
5.查找节点是否存在
#查找节点是否存在
def search(self,item):
curNode = self.__head
while curNode != None:
if curNode.elem==item:
return True
curNode = curNode.next
return False
6.判断链表是否为空
#判断当前链表是否为空
def is_empty(self):
return self.__head == None
7.当前链表的长度
#当前链表的长度
def length(self):
count = 0
curNode = self.__head
while curNode != None:
count += 1
curNode = curNode.next
return count
8.遍历链表
#遍历
def travel(self):
curNode = self.__head
while curNode != None:
print(curNode.elem,end='\t')
curNode = curNode.next
全部代码粘贴
class Node(object):
def __init__(self,elem):
self.elem = elem
self.prev = None
self.next = None
#构建双向链表类
class DoubleLinkList:
#初始化方法
def __init__(self,node=None):
if node!=None:
headNode = Node(node)
self.__head=headNode
else:
self.__head=node
# print(self.__head)
#在头部添加元素
def add(self,item):
node = Node(item)
#判断是否是空列表
if self.is_empty():
self.__head = node
else:
# 将新节点的链接域next指向头结点
node.next=self.__head
#将__head 的头节点的prev指向node
self.__head.prev = node
#将链表头__head指向新节点
self.__head = node
#尾部追加
def append(self,item):
node = Node(item)
curNode = self.__head
#链表为空和不为空的情况
if self.is_empty():
self.__head = node
else:
while curNode.next !=None:
curNode = curNode.next
curNode.next = node
#将node节点的前驱指向当前节点
node.prev = curNode
#指定位置添加
def insert(self,post,item):
#如果post插入位置小于等于0,属于头部插入
if (post-1)<=0:
self.add(item)
# 如果post插入位置大于等于链表长度,属于尾部插入
elif post>=self.length():
self.append(item)
#正常插入
else:
count = 0
preNode = self.__head
node = Node(item)
while count<(post-1):
count += 1
preNode = preNode.next
node.next=preNode.next
node.prev = preNode
preNode.next.prev = node
preNode.next = node
#删除节点
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
#查找节点是否存在
def search(self,item):
curNode = self.__head
while curNode != None:
if curNode.elem==item:
return True
curNode = curNode.next
return False
#判断当前链表是否为空
def is_empty(self):
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
if __name__ == '__main__':
doubleLinkList = DoubleLinkList()
doubleLinkList.add(1)
doubleLinkList.add(12)
doubleLinkList.append(21)
doubleLinkList.append(22)
doubleLinkList.insert(2,2)
doubleLinkList.remove(23)
doubleLinkList.travel()
栈(stack)
是一种容器,可以存入数据,访问元素,删除元素,(LIFO)
特点:只允许在容器的一端加入元素和输出元素,保证任何时候可以访问、删除的元素都是此前最后存入的那个元素。
栈的实现
class Stack(object):
def __init__(self):
self.__list = []
#压栈
def push(self,item):
self.__list.append(item)
#弹出元素
def pop(self):
return self.__list.pop()
#返回栈顶元素
def peek(self):
return self.__list[len(self.__list)-1]
#判断栈是否为空
def is_empty(self):
return self.__list == []
#计算栈的大小
def size(self):
return len(self.__list)
if __name__ == '__main__':
stack = Stack()
#压栈
stack.push(1)
stack.push(2)
stack.push(3)
stack.push(4)
#弹出
print(stack.pop())
print(stack.pop())
print(stack.pop())
print(stack.pop())
队列(queue)
只允许在一端进行插入操作,另一端进行删除操作的线性表。(FIFO)。允许插入的一端为队尾,允许删除的一端为对头。
队列的实现
class Queue(object):
def __init__(self):
self.__list = []
#进队
def enqueue(self,item):
self.__list.append(item)
# self.__list.insert(0,item)
#出队
def dequeue(self):
return self.__list.pop(0)
# return self.__list.pop()
#判断队列是否为空
def is_empty(self):
return self.__list == []
#计算队列的大小
def size(self):
return len(self.__list)
if __name__ == '__main__':
queue = Queue()
queue.enqueue(1)
queue.enqueue(2)
queue.enqueue(3)
print(queue.size())
print(queue.dequeue())
print(queue.size())
print(queue.is_empty())