# 单向链表
class Linked:
_length = 0
def __init__(self,iterable=None):
self._value = None
self._next = None
self._endvalue = self
if iterable is None: return
for i in iterable:
self.append(i)
@property
def length(self):
return self._length
def append(self,value):
link = Linked()
link._value = value
self._endvalue._next = link
self._endvalue = link
self._length += 1
def iternodes(self):
val = self._next
while val:
yield val._value
val = val._next
def __str__(self):
return "+ " ".join(map(str,self.iternodes())) + "]>"
a = Linked(_ for _ in range(5))
a.append(None)
a.append("5")
a.append("60")
print("长度:",a.length)
print(a)
# for i in a.iternodes():
# print(i)
# 单向链表第二版
class Linked:
class __Link:
__slots__ = "value","next"
def __init__(self,value):
self.value = value
self.next = None
def __init__(self,iterable=None):
self.__start = None #起始值
self.__end = None #结束值
self.__lenght = 0
if iterable is None:return
for i in iterable:
self.append(i)
def __len__(self):
return self.__lenght
def append(self,value):
link = Linked.__Link(value)
if not self:
self.__start = link
self.__end = link
else:
self.__end.next = link
self.__end = link
self.__lenght += 1
def iternodes(self):
val:Linked.__Link = self.__start
while val:
yield val.value
val = val.next
def remove(self,value):
if not self: raise ValueError("{} 值不存在".format(value))
if self.__start.value == value:
self.__start = self.__start.next
else:
val = self.__start
while val:
if val.next and val.next.value==value:
val.next = val.next.next
if not val.next: self.__end = val #刪除的值是最后一个值
return
val = val.next
else:
raise ValueError("{} 值不存在".format(value))
def pop(self):
if self:
val = self.__getitem(self.__lenght-2)
val.next = None
value = self.__end.value
self.__end = val
self.__lenght -= 1
return value
else:
raise IndexError("pop form empty DoubleLink")
def insert(self,num:int,value):
if not isinstance(num, int): raise TypeError("num 必须是int类型,而{}是{}类型".format(num, type(num)))
# 负索引转正索引
num = num if num>=0 else (0 if num+self.__lenght<=0 else num+self.__lenght)
if self.__lenght<=num: #尾部追加
self.append(value)
elif num == 0 :
val = Linked.__Link(value)
val.next = self.__start
self.__start = val
self.__lenght += 1
else:
val = self.__getitem(num-1)
link = Linked.__Link(value)
link.next = val.next
val.next = link
self.__lenght += 1
def __getitem(self,index:int):
if not isinstance(index,int):raise TypeError("index 必须是int类型,而{}是{}类型".format(index,type(index)))
if 0<=index<len(self):
val:Linked.__Link = self.__start
i = 0
while val:
if i==index:
return val
else:
val = val.next
i += 1
else:
raise KeyError("{} 索引错误".format(index))
def __repr__(self):
return "(Linked <" + ",".join(map(str,self.iternodes())) + ">)"
def __iter__(self):
return iter(self.iternodes())
def __add__(self, value):
self.append(value)
return self
def __sub__(self, other):
self.remove(other)
return self
def __getitem__(self, num:int):
return self.__getitem(num).value
def __setitem__(self, key, value):
self.__getitem(key).value = value
link = Linked()
link = link + 0+1+2+3+4+5
link = link-0-2-5
print(link)
link.append(10)
link = link +5 +6
print(link)
link += 6
link -= 4
print(link)
# 双向链表
class DoubleLink:
"""双向链表"""
_length = 0
class __Link:
__slots__ = "value","before","after"
"""帮助记录双向链表元素"""
def __init__(self, value, before=None, after=None):
self.value = value # 当前值
self.before = before # 前一个值
self.after = after # 后一个值
def __init__(self,iterable=None):
self._start = None
self._end = None
if iterable:
for i in iterable:
self.append(i)
@property
def length(self):
return self._length
def append(self,value):
link = DoubleLink.__Link(value)
self._length +=1
if self._end is None: #如果初始值一个都没有,设置初始值
self._end = link
self._start = link
else: #添加链表
self._end.after = link
link.before = self._end
self._end = link
def pop(self):
#集合为空,则抛出异常
if self._end is None:
raise IndexError("pop form empty DoubleLink")
value = self._end.value
self._end = self._end.before #前一个值赋给最后一个值
if self._end is None: #如果为空,证明已经没有数据了,将开始设置为空
self._start = None
self._length = 0
else:
self._end.after = None #修改最后一个值的下一个值
self._length -= 1
return value
def insert(self,index,value):
#检测索引类型
if not isinstance(index,int):
raise TypeError("'{}' object cannot be interpreted as an integer".format(type(index).__name__))
#规范索引
if index >=0 : #正向索引
index = index if index<self._length else self._length #解决正向超界
else: #负向索引
val = index + self._length
index = 0 if val<=0 else val #解决负向超界
#插入值
if self._end is None and self._start is None: #原集合中没有值
self.append(value)
else:
temp = None
if self._length/2 >index: #从开始位置寻找
temp = self._start
for i in range(index):
temp = temp.after
else: #从结束位置寻找
for i in range(self._length - index):
if not temp:
temp = self._end
else:
temp = temp.before
#开始插入
if not temp: #尾部插入
# link = DoubleLink.__Link(value,self._end)
# self._end.after = link
# self._end = link
self.append(value)
elif temp is self._start: #开始位置插入
link = DoubleLink.__Link(value,None, self._start)
temp.before = link
self._start = link
self._length += 1
else: #中间插入
link = DoubleLink.__Link(value,temp.before,temp)
temp.before.after = link
temp.before = link
self._length += 1
def remove(self,value): #移除指定值
link = self._start
# 寻找值对应的link
temp = None
while link:
if value == link.value:
temp = link
break
else:
link = link.after
else: #值不存在,抛出异常
raise ValueError("DoubleLink.remove(x): x not in list")
#修改temp.befor.after 前一个值中指向的下一个值
if temp.before: #移除值
temp.before.after = temp.after
else: #说明是开始值
self._start = temp.after
#修改after.before 后一个值中指向的前一个值
if temp.after:
temp.after.before = temp.before
else: #说明是结束值
self._end = temp.before
self._length -= 1
def iternodes(self):
"""遍历链表"""
link = self._start
while link:
yield link.value
link = link.after
def __repr__(self):
return " + ",".join(map(str,self.iternodes())) + "] >"
if __name__ == "__main__":
dlink = DoubleLink([1,2,3,4,None,5,6])
print(dlink)
print(dlink.pop())
print(dlink,"\t长度;",dlink.length)
dlink.remove(None)
dlink.remove(1)
print(dlink, "\t长度;", dlink.length)
dlink.append(9)
print(dlink, "\t长度;", dlink.length)
dlink.remove(9)
dlink.append(10)
print(dlink, "\t长度;", dlink.length)
dlink.insert(10,5)
dlink.append(9)
dlink.insert(-100, -10)
print(dlink, "\t长度;", dlink.length)
dlink = DoubleLink()
dlink.insert(-100, -20)
dlink.insert(-100, -30)
dlink.insert(0, 0)
dlink.insert(2, 2)
dlink.insert(4, 4)
dlink.insert(100, 5)
print(dlink, "\t长度;", dlink.length)
for i in range(dlink.length-3):
dlink.pop()
print(dlink, "\t长度;", dlink.length)
# 双向链表第二版
class DoubleLink:
"""双向链表"""
class __Link:
"""帮助记录双向链表元素"""
def __init__(self, value, before=None, after=None):
self.value = value # 当前值
self.before = before # 前一个值
self.after = after # 后一个值
def __init__(self,iterable=None):
self._start = None
self._end = None
self._length = 0
if iterable:
for i in iterable:
self.append(i)
@property
def length(self):
return self._length
def append(self,value):
link = DoubleLink.__Link(value)
self._length +=1
if self._end is None: #如果初始值一个都没有,设置初始值
self._end = link
self._start = link
else: #添加链表
self._end.after = link
link.before = self._end
self._end = link
def pop(self):
#集合为空,则抛出异常
if self._end is None:
raise IndexError("pop form empty DoubleLink")
value = self._end.value
self._end = self._end.before #前一个值赋给最后一个值
if self._end is None: #如果为空,证明已经没有数据了,将开始设置为空
self._start = None
self._length = 0
else:
self._end.after = None #修改最后一个值的下一个值
self._length -= 1
return value
def insert(self,index,value):
#检测索引类型
if not isinstance(index,int):
raise TypeError("'{}' object cannot be interpreted as an integer".format(type(index).__name__))
#规范索引
if index >=0 : #正向索引
index = index if index<self._length else self._length #解决正向超界
else: #负向索引
val = index + self._length
index = 0 if val<=0 else val #解决负向超界
#插入值
if self._end is None and self._start is None: #原集合中没有值
self.append(value)
else:
temp = None
if self._length/2 >index: #从开始位置寻找
temp = self._start
for i in range(index):
temp = temp.after
else: #从结束位置寻找
for i in range(self._length - index):
if not temp:
temp = self._end
else:
temp = temp.before
#开始插入
if not temp: #尾部插入
# link = DoubleLink.__Link(value,self._end)
# self._end.after = link
# self._end = link
self.append(value)
elif temp is self._start: #开始位置插入
link = DoubleLink.__Link(value,None, self._start)
temp.before = link
self._start = link
self._length += 1
else: #中间插入
link = DoubleLink.__Link(value,temp.before,temp)
temp.before.after = link
temp.before = link
self._length += 1
def remove(self,value): #移除指定值
link = self._start
# 寻找值对应的link
temp = None
while link:
if value == link.value:
temp = link
break
else:
link = link.after
else: #值不存在,抛出异常
raise ValueError("DoubleLink.remove(x): x not in list")
#修改temp.befor.after 前一个值中指向的下一个值
if temp.before: #移除值
temp.before.after = temp.after
else: #说明是开始值
self._start = temp.after
#修改after.before 后一个值中指向的前一个值
if temp.after:
temp.after.before = temp.before
else: #说明是结束值
self._end = temp.before
self._length -= 1
def iternodes(self):
"""遍历链表"""
link = self._start
while link:
yield link.value
link = link.after
def __repr__(self):
return " + ",".join(map(str,self.iternodes())) + "] >"
def __len__(self):
return self._length
def __iter__(self):
return iter(self.iternodes())
def __getitem__(self, index:int):
return self.__getitem(index).value
def __setitem__(self, index:int, value):
self.__getitem(index).value = value
def __add__(self, other):
self.append(other)
return self
def __radd__(self, other):
self.insert(0,other)
return self
def __sub__(self, other):
self.remove(other)
return self
def __getitem(self, index:int):
if 0<=index<self.length:
if index<=self.length//2: #正向寻找
link:DoubleLink.__Link = self._start
for i in range(index):
link = link.after
return link
else: #反向寻找
link:DoubleLink.__Link = self._end
for i in range(self.length - index-1):
link = link.before
return link
else:
raise KeyError("{} DoubleLink index out of range".format(index))
if __name__ == "__main__":
dlink = DoubleLink([1,2,3,4,None,5,6])
print(dlink)
print(dlink.pop())
print(dlink,"\t长度;",dlink.length)
dlink.remove(None)
dlink.remove(1)
print(dlink, "\t长度;", dlink.length)
dlink.append(9)
print(dlink, "\t长度;", dlink.length)
dlink.remove(9)
dlink.append(10)
print(dlink, "\t长度;", dlink.length)
dlink.insert(10,5)
dlink.append(9)
dlink.insert(-100, -10)
print(dlink, "\t长度;", dlink.length)
dlink = DoubleLink()
dlink.insert(-100, -20)
dlink.insert(-100, -30)
dlink.insert(0, 0)
dlink.insert(2, 2)
dlink.insert(4, 4)
dlink.insert(100, 5)
print(dlink, "\t长度;", dlink.length)
for i in range(dlink.length-3):
dlink.pop()
print(dlink, "\t长度;", dlink.length)
print(dlink[1])
dlink += 5
dlink +5+6+9
5+dlink+6+9
print(dlink)
dlink -5-0-9-6-9-5-6-5-2-(-30)
5+dlink+6+7+9
print(dlink)
dlink[0] = -10
print(dlink)
class Node:
__slots__ = 'item next prev'.split()
def __init__(self, item, next=None, prev=None):
self.item = item
self.next = next # Node instance
self.prev = prev # Node instance
def __repr__(self):
return "{} <== {} ==> {}".format(
self.prev.item if self.prev else None,
self.item,
self.next.item if self.next else None
)
class LinkedList: # Double
def __init__(self):
self.head = None
self.tail = None # ?
self._size = 0
def append(self, value):
node = Node(value) # 下一个是None的节点
if self.tail is None: # empty
self.head = node
else:
self.tail.next = node
node.prev = self.tail
self.tail = node
self._size += 1
return self
def __add__(self, item):
return self.append(item)
def insert(self, index, value):
if index >= len(self):
self.append(value)
return
if index < -len(self):
index = 0
current = self[index]
# 找到了,容器非空
newnode = Node(value)
prev = current.prev
next = current
# 开头插入
if prev is None: # i==0 index==0 self.head == current
self.head = newnode
else: # 非开头
newnode.prev = prev
prev.next = newnode
newnode.next = next
next.prev = newnode
self._size += 1
def pop(self):
if self.tail is None:
raise Exception("empty")
node = self.tail
prev = node.prev
# only one
if prev is None:#self.head.next is None:
self.head = None
self.tail = None
else:
prev.next = None
self.tail = prev
value = node.item
self._size -= 1
return value
def remove(self, index):
if self.tail is None:
raise Exception("empty")
current = self[index]
prev = current.prev
next = current.next
if prev is None and next is None:#self.head == self.tail just one
self.head = None
self.tail = None
elif prev is None: # 头
self.head = next
next.prev = None
elif next is None: # 尾
self.tail = prev
prev.next = None
else: # 中间
prev.next = next
next.prev = prev
del current
self._size -= 1
def iternodes(self, reverse=False):
current = self.tail if reverse else self.head
while current:
yield current
current = current.prev if reverse else current.next
# 容器
def __len__(self):
return self._size
size = property(lambda self: self._size)
def __getitem__(self, index):
if index >= len(self) or index < -len(self):
raise IndexError('out of index : {}'.format(index))
reverse = True if index < 0 else False
start = 1 if index < 0 else 0
for i, node in enumerate(self.iternodes(reverse), start):
if i == abs(index):
return node
def __setitem__(self, index, value): # 改
self[index].item = value
def __reversed__(self): # 此魔术方法可以不实现,但是要使用reversed内建函数,必须有__len__和__getitem__
# for x in self.iternodes(True):
# yield x
#yield from self.iternodes(True)
return self.iternodes(True)
# def __iter__(self):
# return self.iternodes()
__iter__ = iternodes
def __contains__(self, item):
print(item, '~~~~~~~~~~~~~~~~~')
current = self.head
while current:
if item == current.item:
return True
current = current.next
return False
ll = LinkedList()
ll + 1 + 2 + 3 + 4 + 5
ll.insert(0, 'start')
ll.insert(1000, 'end')
for x in ll:
print(x)
print('-' * 30)
print(ll[1], len(ll))
print()
for x in reversed(ll):
print(x)
print(2 in ll)
ll[0] = 'start~~~~'
print('-' * 30)
for x in ll:
print(x)
[外链图片转存失败(img-4iaZh1I6-1563623371007)(https://raw.githubusercontent.com/1263351411/xdd.github.io/master/img/python/link_005.jpg)]
class StaticMethod:
"""静态方法装饰器,类似于staticMethod"""
def __init__(self,fn):
self.fn = fn
def __get__(self, instance, owner):
return self.fn
class ClassMethod:
"""类方法装饰器,类似于classmethod"""
def __init__(self,fn):
self.fn = fn
def __get__(self, instance, owner):
def _fn(*args,**kwargs):
return self.fn(owner,*args,**kwargs)
functools.update_wrapper(_fn,self.fn)
# return functools.partial(self.fn,owner) #也可以使用偏函数
return _fn
class Property:
def __init__(self,fn):
self._fn = fn
def setter(self,fn):
self.set = fn
return self
def deleter(self,fn):
self.defn = fn
return self
def __delete__(self, instance):
self.defn(instance)
def __get__(self, instance, owner):
return self._fn(instance)
def __set__(self, instance, value):
# print("---set")
self.set(instance,value)
class A:
def __init__(self,data):
self._data = data
@Property
def data(self):
return self._data
@data.setter
def data(self,value):
self._data = value
@data.deleter
def data(self):
print("data被銷毀了")
a = A("tom")
print(a.data)
a.data = 5
print(a.data)
del a.data
print("-----------演示完成")
class Property:
"""自己实现property和Property功能一样"""
def __init__(self,fn):
self._fn = fn
def setter(self,fn):
self.set = fn
return self
def deleter(self,fn):
self.defn = fn
return self
def __delete__(self, instance):
if hasattr(self,"defn"):
self.defn(instance)
def __get__(self, instance, owner):
return self._fn(instance)
def __set__(self, instance, value):
if not hasattr(self,"set"):
raise AttributeError("can't set attribute")
self.set(instance,value)