尝试用Python实现链表,实现了添加元素append(), 删除元素pop(),获取元素getItem(),设置元素setItem(),打印链表printChain(),输出链表长度getLen()功能,并尝试逐步进行优化,特此记录。
1. 基础版本。
此版本的主要问题有:(1)没有对index进行验证;(2)定位前一个元素的代码冗余。
class ChainCell():
'''本类是链表的基础元素类'''
def __init__(self,value=None,nextCell=None):
self.value=value;
self.next=nextCell;
class Chain():
'''本类实现链表'''
def __init__(self,values=None):
'''初始化函数,如果有初始元素,要求以链表或者元组的形式传递'''
self.head=None
if values:
self.length=0
for value in values:
newCell=ChainCell(value)
if not self.head:
self.head=newCell
else:
self.last.next=newCell
self.last=newCell
self.length+=1
def append(self,value,index=-1):
'''向链表中的index位置添加元素'''
newCell=ChainCell(value)
if index==-1 or index==self.length:
self.last.next,self.last=newCell,newCell
elif index==0 or index==-self.length-1:
newCell.next=self.head
self.head=newCell
else:
lastCell=self.head
n=index-1 if index>0 else self.length-abs(index)
for i in range(n):
lastCell=lastCell.next
newCell.next=lastCell.next
lastCell.next=newCell
self.length+=1
return value
def pop(self,index=-1):
'''弹出链表中的元素'''
# 没有办法直接删除最后一个元素,因为要修改上一个元素的next指针
if index==0:
self.head=self.head.next
else:
n=index-1 if index>0 else self.length-abs(index)-1
lastCell=self.head
for i in range(n):
lastCell=lastCell.next
lastCell.next=lastCell.next.next
self.length-=1
def getCell(self,index):
'''对应“查”功能,是链表最基础的功能,时间复杂度为O(n)\
根据下标,获得某个链表元素的值,支持正负两种下标表示形式'''
if index==0:
return self.head.value
else:
lastCell=self.head
n=index if index>0 else self.length-abs(index)+1
for i in range(n):
lastCell=lastCell.next
return lastCell.value
def setCell(self ,index,value):
'''根据下标,设置某个链表元素的值'''
lastCell=self.head
n=index-1 if index>0 else self.length-abs(index)-1
for i in range(n):
lastCell=lastCell.next
lastCell.next.value=value
return value
def printChain(self):
'''输出所有的链表元素'''
# for i in range(self.length): 两种遍历方式
if not self.head: #或者if self.length==0
print('当前链表中没有元素!')
return
else:
lastCell=self.head
values=[lastCell.value]
while lastCell.next:
lastCell=lastCell.next
values.append(lastCell.value)
print(values)
def getLen(self):
'''输出链表的长度'''
# return self.length 最简单,适合维护了这个变量的情况
if not self.head:
return
else:
count=1
lastCell=self.head
while lastCell.next:
lastCell=lastCell.next
count+=1
return count
2. 修改版本1
定义函数checkLegal判断index 是否合法
'''链表,注意正负坐标的转化,abs(posiIndex)+abs(negaIndex)=self.length\
另外需要注意到底是定位到index前一个元素,还是index元素本身'''
class ChainCell():
'''本类是链表的基础元素类'''
def __init__(self,value=None,nextCell=None):
self.value=value;
self.next=nextCell;
class Chain():
'''本类实现链表'''
def __init__(self,values=None):
'''初始化函数,如果有初始元素,要求以链表或者元组的形式传递'''
self.head=None
if values:
self.length=0
for value in values:
newCell=ChainCell(value)
if not self.head:
self.head=newCell
else:
self.last.next=newCell
self.last=newCell
self.length+=1
def checkLegal(self,index,funcName=None):
'''该函数为类的内部函数,用来判断用户输入的下标是否合理,如果不合理,则会报错,如果合理,则将index原路返回。
funcName为函数的名称,因为append函数比get等函数的边界大一'''
maxLength=self.length if funcName=='append' else self.length-1
if index>maxLength or (index<0 and abs(index)>maxLength+1)