2020年4月14日22:18:03
单链表需要有的的操作:
- 判断链表是否为空is_empty()
- 长度
- 遍历整个链表
- 链表头部添加元素add(item)
- 链表尾部添加元素append(item)
- 指定位置添加元素insert(pos,item)
- 删除节点
- 查找节点是否存在
节点类:
class ListNode:
def __init__(self, x):
self.elem = x
self.next = None
单链表类:(要能把节点串联起来,能具有上述8个操作的功能),还需要有链表头的地址
# 链表计数从0开始
class SingleLinkList(object):
# 写功能时注意特例空链表
def __init__(self, node=None): #如果新建链表的时候没有设立第一个节点,则默认为None
self.__head = node
#这个head的只是自己要用,私有的,外面不需要使用这个,只使用八个方法,所以要加__
def is_empty(self):
return self.__head == None
def length(self): # 要想知道长度,需要遍历计数
cur = self.__head # 当前遍历到的节点cur,是游标
count = 0 # 用来记录数量
while cur != None:
#截止条件是cur == None还是cur.next == None?用前者,因为进入循环的第一步是count计数
#如果cur.next == None,则最后一个数还没被计入长度就结束了
count += 1
cur = cur.next
return count
def travel(self):
# 遍历
cur = self.__head
while cur != None:
print(cur.elem)
cur = cur.next
def add(self,item): #在链表头加入节点,相当于头部指向新节点,新节点的next指向原本第一个节点
# 注意操作顺序,得先连next,在操作head,不然原链表无法通过head找到,会丢掉
node = ListNode(item)
node.next = self.__head
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
def insert(self, pos, item):
"""指定位置添加元素
pos为了和之前定义的那些变量一致,也应该从0开始
还是先把新节点的next连上原来的,在操作原链表前一个节点的next,因此也需要对前一个节点设一
个变量来表示,这里用pre
"""
# 两种特殊情况,注意比较符号
if pos <= 0:
self.add(item)
elif pos > self.length()-1:
self.append(item)
i = 0
pre = self.__head
while i < pos - 1:
i += 1
pre = pre.next
#当循环推出后,pre指向pos-1位置
node = Node(item)
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
else:
pre = cur
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
Python中的=号只是把指向改变了
比如第一个节点node1的next=node2,则next是指向了node2,不是next变成了一个节点
单向循环列表:
尾节点指向头节点
# 单向循环链表
class SingleLinkList(object):
# 写功能时注意特例空链表
def __init__(self, node=None): #如果新建链表的时候没有设立第一个节点,则默认为None
self.__head = node
if node:
node.next = node
#这个head的只是自己要用,私有的,外面不需要使用这个,只使用八个方法,所以要加__
def is_empty(self):
return self.__head == None
def length(self): # 要想知道长度,需要遍历计数
cur = self.__head # 当前遍历到的节点cur,是游标
# 注意这里与一般链表不一样,因为后面的循环判断条件不同
if self.is_empty():
return 0
count = 1
while cur.next != self.__head: # 注意这里只能cur.next,因为一开始cur就等于
# 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='') # end换行
cur = cur.next
#循环结束的时候是遍历到最后一个,但是没进入循环,没有打印,所以补上
print(cur.elem)
def add(self,item): #在链表头加入节点,相当于头部指向新节点,新节点的next指向原本第一个节点
# 注意操作顺序,得先连next,在操作head,不然原链表无法通过head找到,会丢掉
if self.is_empty():
self.__head = node
node.next = node
node = ListNode(item)
cur = self.__head
while cur.next != self__head:
cur = cur.next
node.next = self.__head # self.__head指向的是原本的第一个节点
self.__head = node # 现在访问self.__head相当于访问新加的node
# 考虑特殊情况,空链表是否满足?不行,如果是空,就没有cur.next,所以在前面补上
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
node.next = self.__head
cur.next = node
def insert(self, pos, item):
"""指定位置添加元素
pos为了和之前定义的那些变量一致,也应该从0开始
还是先把新节点的next连上原来的,在操作原链表前一个节点的next,因此也需要对前一个节点设一
个变量来表示,这里用pre
"""
# 两种特殊情况,注意比较符号
if pos <= 0:
self.add(item)
elif pos > self.length()-1:
self.append(item)
i = 0
pre = self.__head
while i < pos - 1:
i += 1
pre = pre.next
#当循环推出后,pre指向pos-1位置
node = Node(item)
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
else:
pre = cur
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