标签:node head .__ 第三章 cur self next --- 数据结构
目录
第三章
链表的提出
线性表:顺序表+链表
顺序表是按顺序排列的,链表是用线串起来的(可以随意添加、删除元素)
链表操作的要点是搞清楚先切断谁,再连接谁
Li=[200,400,600]
三个单链表节点如下:
数据区 | 链接区 | |
0×11 | 200 | 0×34 |
数据区 | 链接区 | |
0×34 | 400 | 0×88 |
数据区 | 链接区 | |
0×88 | 600 | None |
python中变量标识的本质
python中的地址是什么数据类型?
a = 10
b = 20
a,b = b,a(改变的只是a,b存储单元中的地址)
a和b是存储单元,存储的是10,20这两个数值的地址
python中=就是产生一个引用的链接
单链表
单向链表指箭头方向必须从前一个节点指向后一个节点(数据区+后继节点)
第一个节点叫头节点,最后一个节点叫尾节点(空)
单链表中每个单元(节点)有两部分,一个是元素,一个是下一个节点的标识
class SingleNode(object):
def __init__(self,item):
"""单链表的结点"""
self.item = item # _item存放数据元素
self.next = None # _next是下一个节点的标识
基本操作会有两个类产生,一个是节点类,一个是链表类
is_empty()链表是否为空
length()链表长度
travel()遍历整个链表:可以打印出链表中每个节点
add(item)链表头部添加元素
append(item)链表尾部添加元素
insert(pos,item)指定位置添加元素
remove(item)删除节点---删除从列表头找到的第一个元素
search(item)查找节点是否存在
__head | __head.next | ||||
100 | 20 | “ ” | 300 | None |
# coding:utf-8
class Node(object):
""""节点的类"""
def __init__(self,elem):
self.elem = elem
self.next = None
pass
# node = Node(100)
class SingleLinkList(object):
"""单链表的类"""
def __init__(self,node=None):
self.__head = node # 对外不暴露的私有属性 头加__
def is_empty(self): # 这些都是对象操作self
"""链表是否为空"""
return self.__head == None #判断为空
def length(self):
"""链表长度"""
cur = self.__head # cur游标,用来移动遍历节点
count = 0 # count记录数量,判断最后的位置
while cur != None: # cur不等于None
count += 1
cur = cur.next
return count
def travel(self):
"""遍历整个链表"""
cur = self.__head
while cur != None:
print(cur.elem,end=' ') # python3中,end=''代表禁止换行————python2中仅用,即可
cur = cur.next
# print("") #换行
def add(self,item): # 需要反传参数
"""链表头部添加元素,头插法"""
node = Node(item) #首先构造要插入的节点
node.next = self.__head #让节点的尾部指向原链表的头部
self.__head = node
def append(self,item):
"""链表尾部添加元素,尾插法"""
node = Node(item)
if self.is_empty():
self.__head = node # 先判断链表是否为空,若是空链表,则将_head指向新节点
else:
cur = self.__head # 若不为空,则找到尾部,将尾节点的next指向新节点
while cur.next != None:
cur = cur.next
cur.next = node
def insert(self,pos, item):
"""指定位置添加元素
:param pos 从0开始索引
"""
if pos <= 0:
self.add(item)
elif pos > (self.length()-1):
self.append(item)
else:
node = Node(item)
pre = self.__head # piror
count = 0
while count < (pos-1):
pre = pre.next
count +=1
# 当循环推出后,pre指向 pos-1位置
node.next = pre.next
pre.next = node
def remove(self,item):
"""删除节点"""
cur = self.__head
pre = None
while cur != None:
if cur.elem == item:
# 先判断此节点是否为头节点
if cur == self.__head:
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: #cur不等于none才可以进入循环
if cur.elem == item:
return True
else:
cur = cur.next
return False
if __name__ == "__main__":
ll = SingleLinkList()
print(ll.is_empty())
print(ll.length())
ll.append(1)
print(ll.is_empty())
print(ll.length())
ll.append(2)
ll.add(8)
ll.append(3)
ll.append(4)
ll.insert(-1,9)
ll.insert(2,100)
ll.insert(10,200)
ll.travel()
print("")
print(ll.search(100))
ll.remove(9)
ll.travel()
后继节点:当前节点的下一个节点next
要遍历就要用循环while
单链表与顺序表的对比
链表不能一次性定位到pos,需要循环。顺序表可以一次定位。
链表的节点在内存中可以分散,但时间复杂度高了。顺序表的空间必须是连续的,而且顺序表存储空间不够时需要重新申请空间。
双向链表
双向链表中的节点与单链表不同,另外保存前面节点的位置。如下:
前驱节点+数据区+后继节点
可以把类的代码进行封装,后面再建新的类的时候,把之前的类当作object,可以达到类的继承
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 is 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.elem,end=" ")
cur = cur.next
def add(self,item):
"""链表头部添加元素"""
node = Node(item)
node.next = self.__head
self.__head = node # self.__head.prev = node self.__head = node也可以
node.next.prev = 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
node.prev = cur
def insert(self,pos, item):
"""指定位置添加元素"""
if pos <=0: #从0开始数
self.add(item)
elif pos > (self.length()-1):
self.append(item)
else:
cur = self.__head
count = 0
while count < pos :
count +=1
cur = cur.next
node = Node(item)
node.next = cur
node.prev = cur.prev
cur.prev.next = node
cur.prev = 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: #如果cur.next存在,进入if,否则退出
# 判断链表是否只有一个节点
cur.next.prev = None
else:
cur.prev.next = cur.next
if cur.next:
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
if __name__ == "__main__" :
dll = DoubleLinkList()
print(dll.is_empty())
print(dll.length())
dll.append(1)
print(dll.is_empty())
print(dll.length())
dll.append(2)
dll.add(8)
dll.append(9)
dll.append(3)
dll.append(4)
dll.insert(-1, 9)
dll.insert(2, 100)
dll.insert(10, 200)
dll.travel()
print("")
print(dll.search(100))
dll.remove(9)
dll.travel()
单向循环链表
单向循环链表是单链表的一种变形,链表中最后一个节点的next不再是None,而是指向链表的头节点。
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):
"""链表长度"""
if self.is_empty():
return 0
cur = self.__head
count = 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
print(cur.elem)
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
node.next = self.__head
self.__head = node
cur.next = self.__head # node
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
node.next = self.__head
def insert(self,pos, item):
"""指定位置添加元素"""
if pos <=0: #从0开始数
self.add(item)
elif pos > (self.length()-1):
self.append(item)
else:
node = Node(item)
pre = self.__head
count = 0
while count < (pos-1) :
pre = pre.next
count +=1
node.next = pre.next
pre.next = node
def remove(self,item):
"""删除节点 - --删除从列表头找到的第一个元素"""
if self.is_empty():
return
cur = self.__head
pre = None
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
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 = self.__head
def search(self,item):
"""查找节点是否存在"""
if self.is_empty():
return False
cur = self.__head
while cur.next != self.__head:
if cur.elem == item:
return True
else:
cur = cur.next
# 退出循环,指向尾节点
if cur.elem == item:
return True
return False
if __name__ == "__main__":
ll = SingleCycleLinkList()
print(ll.is_empty())
print(ll.length())
ll.append(1)
print(ll.is_empty())
print(ll.length())
ll.append(2)
ll.add(8)
ll.append(9)
ll.append(3)
ll.append(4)
ll.insert(-1, 9)
ll.insert(2, 100)
ll.insert(10, 200)
ll.travel()
print("")
print(ll.search(100))
ll.remove(9)
ll.travel()
标签:node,head,.__,第三章,cur,self,next,---,数据结构 来源: https://blog.csdn.net/weixin_46489969/article/details/122788588
本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享; 2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关; 3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关; 4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除; 5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。