class Node(object):
'''节点类'''
def __init__(self, elem):
self.elem = elem
self.next = None类内部的 __init__函数,是初始化函数,只要是类的实例对象,就会自动执行__init__函数内部的代码块,也就是说,类的实例对象都会有__init__函数的属性
ex:
__node = Node()____node__就是Node类的__实例__对象
该node具有__elem__和__next__属性
[========]
class SingleLinkList():
def __init__(self, node=None):
self.__head = node1. 定义实例的首节点属性,该属性为实例的私有属性
self__head = node表示self的head属性是self私有的
2. 链表可以定义为空, 但是空链表内必须存在首节点,node=None,默认的首节点指向None,但以传递进来的首节点node为准
def __init__(self, node=None):
slef.__head=nodenode在函数的参数元祖内, 如果不传递node,默认的node的值为None
ex1:
linklist = SingleLinkList()
- 创建一个SingleLinkList类的实例对象
ex2:
linklist = SingleLinkList(110)
- 创建一个SingleLinkList类的实例对象
[========]
1. 所有的内置方法
def __init__(self, node=None):
"""SingleLinkList类初始化,私有的,首节点方法"""
self.__head = node
def is_empty(self):
"""链表是否为空"""
def length(self):
"""链表的长度"""
def tarvel(self):
"""遍历整个链表"""
def add(self, item):
"""链表头部添加元素, 首插法"""
def append(self, item):
"""链表尾部添加元素, 尾插法"""
def insert(self, pos, item):
"""指定位置插入元素"""
def remove(self, item):
"""删除节点"""
def search(self, item):
"""查找节点是否存在"""[========]
ex:
linklist= SingleLinkList()创建一个实例对象
linklist.is_empty()调用该实例的is_empty方法
[========]
1. is_empty()
def is_empty(self):
return self.__head == None__作用:__判断该链表是否为空
步骤详解:
self.__head是该链表的首节点,self._head==None,就表示该链表首节点为None,即该链表没有节点[========]
2. length()
def length(self):
cur = self.__head
count = 0
while cur != None:
count += 1
cur = cur.next
return count__作用:__查看该链表的长度
步骤详解:
cur = self.__head创建游标,起始是指向链表的首节点
count = 0创建count,起始值为0,进行数数
while cur != None:遍历所有元素
1.判断条件:如果游标(cur)指向的不是None,就一直循环.
2.最后一个节点的next域指向的就是None
3.当cur == None的时候,就是已经遍历完所有的节点
count += 1如果游标cur所指向的节点不是None,则执行count加一操作
cur = cur.next将游标cur进行后移一位
return count返回count的数值
注意点:
1. 如果该链表为空怎么办?
cur = self.__headcount=0已经设置好了;while cur != None:return count 返回count的值02. cur == None 与 cur.next == None的判断条件的问题
cur == None表示当前游标指向的节点为Nonecur.next == None表示当前游标指向的节点的后继节点为None[========]
3. tarvel()
def tarvel(self):
cur = self.__head
while cur != None:
print(cur.elem, end=" ")
cur = cur.next
print("")__作用:__遍历所有节点[遍历整个链表]
步骤详解:
cur = self.__headwhile cur != None:print(cur.elem, end=" ")cur = cur.nextprint("")注意点:
1. 如果该链表为空怎么办?
cur = self.__headwhile cur != None:print("")2. cur == None 与 cur.next == None的判断条件的问题
cur == None表示当前游标指向的节点为Nonecur.next == None表示当前游标指向的节点的后继节点为Nonecur.next == None,则会丢掉最后一个元素[========]
4. add():
def add(self, item):
node = Node(item)
node.next = self.__head
self.__head = node__作用:__链表头部添加元素, 首插
步骤详解:
node = Node(item)self.__head首节点指向新节点,那么就会丢失原有的所有节点node.next = self.__headself.__head指向现在的新节点self.__head = node注意点:
slef.__head = None[========]
5. append()
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 = Node(item)if self.is_empty():self.__head = nodecur = self.__headwhile cur.next != None:cur = cur.nextcur.next = node[========]
6. insert()
def insert(self, pos, item):
if pos <= 0:
self.add(item)
elif pos > (self.length()-1):
self.append(item)
else:
node = Node(item)
pro = self.__head
count = 0
while count < (pos-1):
count += 1
pro = pro.next
node.next = pro.next
pro.next = node__作用:__指定位置插入节点
步骤详解:
if pos <= 0:self.add(item)elif pos > (self.length()-1):self.append(item)3.
else:
进入插入节点的代码体
node = Node(item)
创建一个新节点
pro = self.__head
创建游标
count = 0
我们计数的方式来控制游标
while count < (pos-1):
当下标到pos前一位元素的时候,结束循环
count += 1
pro = pro.next
游标向后移动一位
node.next = pro.next
新节点的next域指向pos上一个位置处的next域的指向
pro.next = node
将pos上一个位置处的next域指向新节点
注意: 如果给定的下标等于尾部下标,就等于是在尾部下标处添加元素,原有的尾部元素要向后移动一位, 我们把他归类到插入节点的代码中
[========]
7. search()
def search(self, item):
cur = self.__head
while cur != None:
if cur.elem == item:
return True
else:
cur = cur.next
return False__作用:__查找节点是否存在
cur = self.__headwhile cur != None:if cur.elem == item:return Trueelse:cur = cur.next游标向后移动一位return False[========]
8. remove()
def remove(self, item):
cur = self.__head
pro = None
while cur != None:
if cur.elem == item:
if cur == self.__head:
self.__head = cur.next
else:
pro.next = cur.next
break
else:
pro = cur
cur = cur.next作用:_删除节点
cur = self.__headpro = Nonewhile cur != None:if cur.elem == item:if cur == self.__head:self.__head = cur.next3.
else:
pro.next = cur.next
item如果不是首节点的elem,
直接将当前节点的__前一个节点的next域__指向当前节点的__后继节点的next域__
4.break
pro = cur
pro为cur的上一个元素的游标
cur = cur.next
注意: pro与cur的位置不能颠倒
注意点:
操作 链表 顺序表
访问元素 O(n) O(1)
从头部删除元素 O(1) O(n)
从尾部删除元素 O(n) O(1)
在中间插入元素 O(n) O(n)
链表失去了顺序表随机读取的优点,同时链表由于增加了节点的指针域,空间开销比较大,但对存储空间使用要相对灵活
1.主要耗时的操作是遍历查找
2.删除和插入操作本身的复杂度是O(1)
1.主要耗时的操作是拷贝覆盖
2.抛除元素在尾部的情况
顺序表进行插入和删除时,需要对操作点之后的所有元素进行前后移动操作
只能通过拷贝和覆盖的方法进行
原文:https://www.cnblogs.com/amou/p/8979359.html