顺序表:
一个顺序表的完整信息包括两部分,一部分是表中的元素集合,另一部分是为实现正确操作而需记录的信息,即有关表的整体情况的信息,这部分信息主要包括元素存储区的容量和当前表中已有的元素个数两项。
一体式结构顺序表:
存储表信息的单元与元素存储区以连续的方式安排在一块存储区里,两部分数据的整体形成一个完整的顺序表对象。
一体式结构整体性强,易于管理。但是由于数据元素存储区域是表对象的一部分,顺序表创建后,元素存储区就固定了。
分离式结构顺序表:
表对象里只保存与整个表有关的信息(即容量和元素个数),实际数据元素存放在另一个独立的元素存储区里,通过链接与基本表对象关联。
元素存储器替换:
一体式结构由于顺序表信息区与数据区连续存储在一起,所以若想更换数据区,则只能整体搬迁,即整个顺序表对象(指存储顺序表的结构信息的区域)改变了。
分离式结构若想更换数据区,只需将表信息区中的数据区链接地址更新即可,而该顺序表对象不变。
链表:
单向链表:
单向链表也叫单链表,是链表中最简单的一种形式,它的每个节点包含两个域,一个信息域(元素域)和一个链接域。这个链接指向链表中的下一个节点,而最后一个节点的链接域则指向一个空值。
单项链表的操作:
is_empty() 链表是否为空
length() 链表长度
travel() 遍历整个链表
add(item) 链表头部添加元素
append(item) 链表尾部添加元素
insert(pos, item) 指定位置添加元素
remove(item) 删除节点
search(item) 查找节点是否存在
操作思路:
代码实现:
(1)节点实现
class SignleNode(object):
def __init__(self,item):
#self.item 存放数据
self.item = item
#self.next 保存下一个指向下一个节点的地址
self.next = None
(2)单项链表操作
#节点实现
class SignleNode(object):
def __init__(self,item):
self.item = item #self.item 存放数据
self.next = None #self.next 保存下一个指向下一个节点的地址
class SingleLinkList(object):
def __init__(self):
self._head = None
def is_empty(self): #链表是否为空
"""
#Version 1.0
if self.head == None:
return True
else:
return False
"""
#Version 2.0
return self._head == None
def length(self): #链表长度
count = 0 #计算长度
cur = self._head #cur初始指向头节点
while cur != None:
count += 1
cur = cur.next #cur后移一个节点
return count
def travel(self): #遍历整个链表
cur = self._head
while cur != None:
print(cur.item,end=' ')
cur = cur.next
def add(self,item): #链表头部添加元素
node = SignleNode(item)
node.next = self._head
self._head = node
def append(self,item): #链表尾部添加元素
node = SignleNode(item) #定义节点
if self.is_empty(): #空链表,直接头部标识指向新节点即可
self._head = node
else: #非空链表,需要遍历
cur = self._head
while cur.next != None:
cur = cur.next
cur.next = node
def insert(self,pos,item): #指定位置添加元素
#先创建节点
#头部插入 or 尾部插入
#正常插入
"""
#Version 1.0
if pos <=0:
self.add(item)
elif pos >= self.length():
self.append(item)
else:
node = SignleNode(item)
pre = None
cur = self._head
count = 0
while count!= pos:
pre = cur
cur = cur.next
count += 1
pre.next = node
node.next = cur
"""
#Version 2.0
if pos <=0:
self.add(item)
elif pos >= self.length():
self.append(item)
else:
node = SignleNode(item)
pre = self._head #注意这里表示pre指向位置使链表第一个节点,与头标识一样
count = 0
while count < (pos-1):
pre = pre.next
count += 1
node.next = pre.next #先保存插入位置上一节点的指向,赋给插入节点的指向
pre.next = node #将插入位置上一节点指向插入节点
def remove(self,item): #删除节点
pre = None
cur = self._head
while cur != None:
if cur.item == item:
if not pre: #判断是否是要删除第一个节点
self._head = cur.next #若第一个节点,改变头标识的指向
else:
pre.next = cur.next #若不为第一个节点,则指向方向跳过这一节点,而后退出循环
break
else:
pre = cur
cur = cur.next
def search(self,item): #查找节点是否存在
cur = self._head
while cur != None: #遍历
if cur.item == item: #存在返回True
return True
else:
cur = cur.next
return False #遍历结束都不存在返回False
if __name__ == '__main__':
temp = SingleLinkList()
print('is_empty:',temp.is_empty())
temp.add(5)
print('is_empty:',temp.is_empty())
print(temp.travel())
print('length:',temp.length())
temp.add(1)
print(temp.travel())
temp.append(7)
print(temp.travel())
temp.insert(1,3)
print(temp.travel())
temp.remove(3)
print(temp.travel())
print('search_1:',temp.search(1))
链表与顺序表相比较:
双向链表:
(1)概述
(2)操作思路
(3)代码实现
class Node(object):
"""双向链表节点"""
def __init__(self, item):
self.item = item
self.next = None
self.prev = None
class DLinkList(object):
"""双向链表"""
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:
count += 1
cur = cur.next
return count
def travel(self):
"""遍历链表"""
cur = self._head
while cur != None:
print(cur.item,end = " "),
cur = cur.next
def add(self, item):
"""头部插入元素 """
node = Node(item)
if self.is_empty():
# 如果是空链表,将_head指向node
self._head = node
else:
# 将node的next指向_head的头节点
node.next = self._head
# 将_head的头节点的prev指向node
self._head.prev = node
# 将_head 指向node
self._head = node
def append(self, item):
"""尾部插入元素"""
node = Node(item)
if self.is_empty():
# 如果是空链表,将_head指向node
self._head = node
else:
# 移动到链表尾部
cur = self._head
while cur.next != None:
cur = cur.next
# 将尾节点cur的next指向node
cur.next = node
# 将node的prev指向cur
node.prev = cur
def search(self, item):
"""查找元素是否存在"""
cur = self._head
while cur != None:
if cur.item == item:
return True
cur = cur.next
return False
def insert(self, pos, item):
"""在指定位置添加节点"""
if pos <= 0:
self.add(item)
elif pos > (self.length()-1):
self.append(item)
else:
node = Node(item)
cur = self._head
count = 0
# 移动到指定位置的前一个位置
while count < (pos-1):
count += 1
cur = cur.next
# 将node的prev指向cur
node.prev = cur
# 将node的next指向cur的下一个节点
node.next = cur.next
# 将cur的下一个节点的prev指向node
cur.next.prev = node
# 将cur的next指向node
cur.next = node
def remove(self, item):
"""删除元素"""
if self.is_empty():
return
else:
cur = self._head
if cur.item == item:
# 如果首节点的元素即是要删除的元素
if cur.next == None:
# 如果链表只有这一个节点
self._head = None
else:
# 将第二个节点的prev设置为None
cur.next.prev = None
# 将_head指向第二个节点
self._head = cur.next
return
while cur != None:
if cur.item == item:
# 将cur的前一个节点的next指向cur的后一个节点
cur.prev.next = cur.next
# 将cur的后一个节点的prev指向cur的前一个节点
cur.next.prev = cur.prev
break
cur = cur.next
if __name__ == "__main__":
ll = DLinkList()
ll.add(1)
ll.add(2)
ll.append(3)
ll.insert(2, 4)
ll.insert(4, 5)
ll.insert(0, 6)
print("length:",ll.length())
ll.travel()
print(ll.search(3))
print(ll.search(4))
ll.remove(1)
print("length:",ll.length())
ll.travel()
单向循环链表:
(1)概述
(2)操作代码实现
class Node(object):
"""节点"""
def __init__(self, item):
self.item = item
self.next = None
class SinCycLinkedlist(object):
"""单向循环链表"""
def __init__(self):
self._head = None
def is_empty(self):
"""判断链表是否为空"""
return self._head == None
def length(self):
"""返回链表的长度"""
# 如果链表为空,返回长度0
# 画单向链表图来理解
if self.is_empty():
return 0
count = 1
cur = self._head
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.item,end = " ")
cur = cur.next
#最后一个节点在循环里无法打印,单独打印
print(cur.item)
def add(self, item):
"""头部添加节点"""
node = Node(item)
if self.is_empty():
self._head = node
node.next = self._head
else:
#添加的节点指向_head
node.next = self._head
# 移到链表尾部,将尾部节点的next指向node
cur = self._head
while cur.next != self._head:
cur = cur.next
cur.next = node
#_head指向添加node的,等找出最后一个节点后,再更改头节点的指向
self._head = node
def append(self, item):
"""尾部添加节点"""
node = Node(item)
if self.is_empty():
self._head = node
node.next = self._head
else:
# 移到链表尾部
cur = self._head
while cur.next != self._head:
cur = cur.next
# 将尾节点指向node
cur.next = node
# 将node指向头节点_head
node.next = self._head
def insert(self, pos, item):
"""在指定位置添加节点"""
#这里位置下标从0开始
if pos <= 0:
self.add(item)
elif pos > (self.length()-1):
self.append(item)
else:
node = Node(item)
cur = self._head
count = 0
# 移动到指定位置的前一个位置
while count < (pos-1):
count += 1
cur = cur.next
node.next = cur.next
cur.next = node
def remove(self, item):
"""删除一个节点"""
# 若链表为空,则直接返回
if self.is_empty():
return
# 将cur指向头节点
cur = self._head
pre = None
# 若头节点的元素就是要查找的元素item
if cur.item == item:
# 如果链表不止一个节点
if cur.next != self._head:
# 先找到尾节点,将尾节点的next指向第二个节点
while cur.next != self._head:
cur = cur.next
# cur指向了尾节点
cur.next = self._head.next
self._head = self._head.next
else:
# 链表只有一个节点
self._head = None
else:
#pre = self._head
# 第一个节点不是要删除的
while cur.next != self._head:
# 找到了要删除的元素
if cur.item == item:
# 删除
pre.next = cur.next
return
else:
pre = cur
cur = cur.next
# cur 指向尾节点
if cur.item == item:
# 尾部删除
pre.next = cur.next
def search(self, item):
"""查找节点是否存在"""
if self.is_empty():
return False
cur = self._head
#第一个节点就是要查找的节点
if cur.item == item:
return True
while cur.next != self._head:
cur = cur.next
if cur.item == item:
return True
return False
if __name__ == "__main__":
ll = SinCycLinkedlist()
ll.add(1)
ll.add(2)
ll.append(3)
ll.insert(2, 4)
ll.insert(4, 5)
ll.insert(0, 6)
print("length:",ll.length())
ll.travel()
print(ll.search(3))
print(ll.search(7))
ll.remove(1)
print("length:",ll.length())
ll.travel()
end