1、题目描述:单链表的定义、初始化、非空的判断、长度、头插法、尾插法、删除结点;最后两个函数是两个特别的应用。(重点看)
# -*- coding: utf-8 -*-
"""
Created on Thu Apr 05 09:31:13 2018
@author: juan
"""
class Node():
__slots__=['_elem','_next']#限定Node实例的属性
def __init__(self,elem,next1=None):
self._elem=elem
self._next=next1#Node的指针部分默认指向None
class SingleLinkedList():
def __init__(self):#初始化为空链表
self._head=None
def isEmpty(self):#检测链表是否为空
return self._head==None
def prepend(self,elem):#在链表前端添加元素
self._head=Node(elem,self._head)
def append2(self,elem):#在链表后端添加元素
if self._head is None:
self._head=Node(elem)
return#这里很重要,如果不写,会多一个
p=self._head
while p._next:
p=p._next
p._next=Node(elem)
def pop(self):#删除表头结点并返回这个结点里的数据
if self._head is None:
return "none"
e=self._head._elem
self._head=self._head._next
return e
def __len__(self):
pre=self._head
length=0
while pre:
length=length+1
pre=pre._next
return length
def pop_last(self):
if self._head is None:
return "none"
p=self._head
if p._next is None:
e=p._elem
self._head=None
return e
while p._next._next:
p=p._next
e=p._next._elem
p._next=None
return e
def printall(self):#打印所有结点值
p=self._head
while p:
print (p._elem)
p=p._next
def FindKthToTail(self, head, k):#输入一个链表,输出该链表中倒数第k个结点。
if head is None or k==0:
#思路:如果只能从头到尾遍历一次的话,就只能用某个基准去遍历,
#比如说,两个指针相距k-1,然后两个指针一起往后游走。
return "None1"
p=head
q=None
for i in range(k-1):
if p._next:
p=p._next
else:
return "None2"
q=head
while p._next:
p=p._next
q=q._next
return q._elem
def deleteSomeoneNode(self,node):#在O(1)时间复杂度删除该链表节点。
#思路:直接将当前结点的下一节点的内存复制去覆盖当前结点;
#避免了每次都要遍历去寻找当前结点的前一节点。
current=node
current._elem=current._next._elem
current._next=current._next._next
a=SingleLinkedList()
for i in range(5):
a.prepend((i+1)*2)
#print (a.isEmpty())#结果为False
#print a.pop()#结果为10
#print a.__len__()#结果为5
#b=a.pop_last()
#print (b)#结果为2
#c=a.FindKthToTail(a._head,4)
#print c #结果为8
d=a.deleteSomeoneNode(a._head)
a.printall() #结果为8 6 4 2
#注意去掉print,直接调用即可,你的函数本没有return数值,print后那就是个None
3、Q&A:
- 开始出现数组越界的情况,注意代码缩进问题;
- Has no attribute _name,注意参数的一致性