赞
踩
list_data = ['hfdgj',8.0,33,"jdjf",6,3,7]
for i in list_data:
if i==7:
print("pass")
break
timeit
from timeit import Timer
,Timer中需要传入几个参数,因为有初始化的存在,如下图示:from timeit import Timer def t1(): data = [] for i in range(10000): data.extend([i]) def t2(): data =[i for i in range(10000)] def t3(): data = [] for i in range(10000): data=data+[i] def t4(): data = [] for i in range(10000): data.insert(0,1) def t5(): data = [] for i in range(10000): data.append(i) a = Timer("t1()","from __main__ import t1") a_time = a.timeit(100) b = Timer("t2()","from __main__ import t2") b_time = b.timeit(100) c = Timer("t3()","from __main__ import t3") c_time = c.timeit(100) d = Timer("t4()","from __main__ import t4") d_time = d.timeit(100) e = Timer("t5()","from __main__ import t5") e_time = e.timeit(100) print("extend:",a_time,"\n迭代器:",b_time,"\n+:",c_time) print("append:",e_time,"\ninsert:",d_time) -------------------------run_result---------------------- extend: 0.05123333399751573 迭代器: 0.013302958999702241 +: 8.697985875001905 append: 0.028532749998703366 insert: 2.6066741249996994
函数 | 时间复杂度元 |
---|---|
index[i] | O(1) |
append | O(1) |
pop() | O(1) |
pop(i) | O(n) |
insert(i,iterm) | O(n) |
del | O(n) |
reverse | O(n) |
sort | O(nlogn) |
for循环遍历 | O(n) |
使用in判断元素是否存在 | O(n) |
切片取值:list[x,y] | O(k),k等于x到y之间的个数 |
删除列表切片 | O(n) |
设置列表切片 | O(n+k) |
两个列表相加 | O(k),k代表第二个列表中元素的个数 |
两个列表相乘法 | O(nk) |
函数 | 时间复杂度元 |
---|---|
copy | O(n) |
get取值 | O(1) |
set | O(1) |
delete | O(1) |
in判断元素是否在字典中 | O(1) |
for循环遍历 | O(n) |
class Node(): def __init__(self,elem): '''定义链表的节点,elem是数据,next是下个节点的指针''' self.elem = elem self.next = None class Link_List(): def __init__(self,node=None): '''初始化函数,将节点作为一个整体传入''' self._head = node def is_empty(self): ''' 判断非空''' return self._head==None def length(self): ''' 计算链表长度''' ''' 需要一个游标的标识,来记录当前访问到哪个位置上了''' cur= self._head # cur初始值指向head,意味着他指向第一个值 count = 0 # count记录列表中元素的个数 '''不用cur.next=None作为条件,原因是最后一个元素的指针为None 如果以他为判断条件,会少计数1''' while cur !=None: count +=1 '''cur有next用法的原因: cur = self._head = node,node中存在next属性''' cur= cur.next return count def travel(self): ''' 遍历整个链表''' cur = self._head while cur != None: print(cur.elem,end=" ") cur = cur.next print("") def add(self,itrem): ''' 链表头部添加元素''' ''' 最终要达到的效果,新节点的next指向原头部,然后头部节点指向新node''' ''' 修改的时候要注意先后顺序,必须先让新节点的next指向原头部 因为必须根据原头部来确定新节点后需要跟的node,否则会丢节点''' node = Node(itrem)# 数据元素封装为链表的节点 node.next = self._head#新节点的next指向原头部 self._head=node#头部指向新节点 def append(self,itrem): ''' 链表尾部追加元素''' '''先设置新的节点,遍历整个列表之后,将最后一个节点的指针指向新节点''' node = Node(itrem) '''如果链表是一个空列表,那么node就是None,没有next属性,因此需要考虑特殊情况''' 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,itrem): ''' 链表随意位置插入元素 :pos 从0开始索引 ''' '''插入元素,移动的时候要移动到目标元素的前一个位置 现将新节点的node指向下一个元素,:再将前一个的指针指向新节点''' if pos <=0:#小于0,相当于头部插入 self.add(itrem) elif pos >(self.length()-1):#大于列表总长度,相当于尾部添加 self.append(itrem) else: pre = self._head # 可以理解为插入元素的游标,当前指向第一个节点 count = 0 while count < (pos - 1): # 判断让其指向pos的前一个节点 count += 1 pre = pre.next # 当循环退出之后,pre指向pos-1 node = Node(itrem) # 创建新的node节点 node.next = pre.next # pre当前指向的就是要插入的位置,因此先让node指向目标节点 pre.next = node # 然后修改pre的指针,指向node def remove(self,itrem): ''' 删除节点''' '''可以使用两个游标节点,前一个和后一个保持一个节点的距离 删除节点的时候,让前一个节点指向后一个节点所指向的节点''' cur = self._head pre = None while cur!=None: if cur.elem == itrem: # 元素相等的情况下,需要判断是否是头节点, # 因为刚开始pre是None,没有next属性 if cur == self._head: self._head = cur.next else: pre.next = cur.next break else: pre = cur cur = cur.next def search_index(self,pos): ''' 查找元素''' cur = self._head # 可以理解为插入元素的游标,当前指向第一个节点 if pos <=0: print(cur.elem) else: count = 0 while count <=pos : # 判断让其指向pos的前一个节点 count += 1 if count == self.length(): break cur = cur.next print(cur.elem) def search_value_1(self, itrem): cur = self._head count = 0 while count <(self.length()-1): cur = cur.next if cur.elem == itrem: print(count) break count +=1 if count == (self.length()-1): print("pass") def search_value_2(self, itrem): cur = self._head while cur !=None:#cur为None,意味着cur已经走到了链表的最后一位 if cur.elem == itrem: return True else: cur= cur.next return False if __name__ == '__main__': ll = Link_List() print("是否为空:",ll.is_empty()) print("长度:",ll.length()) ll.add(10) ll.insert(pos=1,itrem="ppp") ll.append(1) ll.insert(pos=-1,itrem="fdjfgir") print("是否为空:",ll.is_empty()) print("长度:",ll.length()) ll.append("i") ll.append("love") ll.append("lalal") ll.append(2) ll.append(3) ll.insert(pos=7,itrem="hahaha") ll.search_index(-1) ll.search_value_1("lik") print(ll.search_value_2("i")) ll.travel() ll.remove("fdjfgir") ll.travel() ll.remove(3) ll.travel() ll.remove("i") ll.travel() **************************执行结果*************************** 是否为空: True 长度: 0 是否为空: False 长度: 4 fdjfgir pass True fdjfgir 10 ppp 1 i love lalal hahaha 2 3 10 ppp 1 i love lalal hahaha 2 3 10 ppp 1 i love lalal hahaha 2 10 ppp 1 love lalal hahaha 2
操作 | 链表 | 顺序表 |
---|---|---|
访问元素 | O(n) | O(1) |
在头部插入/删除 | O(1) | O(n) |
在尾部插入/删除 | O(n) | O(1) |
在中间插入/删除 | O(n) | O(n) |
class Node(): def __init__(self,iterm): ''' :param iterm: 传入节点的数据 ''' self.elem= iterm self.next = None#后继指向 self.prev = None#前驱指向 class DoubleLinkList(): '''双链表操作''' def __init__(self,node = None): ''' 双链表初始化函数,链表头指向节点 :param node: 第一个节点 ''' self.__head = node def is_empty(self): ''' 判断是否为空''' return self.__head is None def length(self): '''求长度''' # cur为游标,指向移动的游标,遍历节点 cur = self.__head #count 计算节点数量 count = 0 #遍历节点 while cur != None: count +=1 cur = cur.next # 游标指向下一个节点 return count def travel(self): ''' 遍历链表''' cur = self.__head while cur != None: print(cur.elem,end = " ") cur = cur.next # 游标指向下一个节点 print("") def add(self,iterm): ''' 直接在首节点插入元素,插入时,先将插入节点的N指向原首节点的P 再将头部指向插入节点的P,最后将原首节点的P指向插入节点的N :param iterm: 要插入的元素 ''' #方法一,先将插入node的后继指向原节点的前驱 flag = False # 定义一个标志,用于区分是否是空列表 node = Node(iterm) # 数据元素封装为链表的节点 # 在这里判断的原因是,放在下面,新节点已添加,无法判断链表是否为空 if self.is_empty(): flag = True node.next = self.__head # 新节点的next指向原头部 self.__head = node # 头部指向新节点 if flag == False :# 如果标志不是True,说明链表不为空,就需要执行下面的操作 node.next.prev = node#将原首节点的前驱指向插入节点的后继 def append(self,iterm): ''' 尾部追加元素 :param iterm: :return: ''' '''先设置新的节点,遍历整个列表之后,将最后一个节点的指针指向新节点''' node = Node(iterm) '''如果链表是一个空列表,那么node就是None,没有next属性,因此需要考虑特殊情况''' if self.is_empty(): self.__head = node else: cur = self.__head while cur.next != None: cur = cur.next cur.next = node# 追加时将最后一个节点的后继指向新节点的前驱 node.prev = cur# 再将新节点的前驱指向最后一个节点的后继 def insert(self,pos,iterm): ''' 随机插入元素 :param pos: 插入位置 :param iterm: 插入的元素 ''' if pos <=0:#小于0,相当于头部插入 self.add(iterm) elif pos >(self.length()-1):#大于列表总长度,相当于尾部添加 self.append(iterm) else: pre = self.__head # 可以理解为插入元素的游标,当前指向第一个节点 count = 0 while count <= (pos - 1): # 判断让其指向pos的前一个节点 count += 1 pre = pre.next # 当循环退出之后,pre指向pos-1 node = Node(iterm) # 创建新的node节点 node.next = pre # pre当前指向的就是要插入的位置,因此先让node的后继指向找到的目标节点 node.prev = pre.prev# node的前驱指向前一个节点( pre.prev为前一个节点) pre.prev.next = node#前一个节点的后继指向node pre.prev = node#后一个节点的前驱指向node def remove(self,itrem): ''' 删除元素为elem的节点 :param itrem: 元素信息 ''' cur = self.__head while cur != None: if cur.elem == itrem: # 元素相等的情况下,需要判断是否是头节点, # 因为刚开始pre是None,没有next属性 if cur == self.__head: self._head = cur.next if cur.next !=None:#判断链表是否只有一个节点,是的话就不需要指向了 cur.next.prev = None else: cur.prev.next = cur.next # 要删除节点的前一个节点的后继指向下一个节点 if cur.next !=None: cur.next.prev = cur.prev# 要删除节点的后一个节点的前驱指向前一个节点 break else: cur = cur.next def search(self,iterm): cur = self.__head while cur != None: # cur为None,意味着cur已经走到了链表的最后一位 if cur.elem == iterm: return True else: cur = cur.next return False if __name__ == '__main__': ll = DoubleLinkList() print("是否为空:", ll.is_empty()) print("长度:", ll.length()) ll.add(10) ll.append(100) ll.add(20) ll.travel() ll.insert(1,"haha") ll.travel() ll.remove(100) ll.travel() print(ll.search(10)) ***********************run——result***************** 是否为空: True 长度: 0 20 10 100 20 haha 10 100 20 haha 10 True
在这里插入代码片class Node(): def __init__(self,iterm): ''' :param iterm: 传入节点的数据 ''' self.elem= iterm self.next = None#后继指向 class ForLinkList(): '''单向循环操作''' def __init__(self,node = None): ''' 单向循环链表表初始化函数,节点的next指向下一个节点 最后一个节点的next区域指向头节点 如果链表只有一个节点,就是节点的next区域指向自己 :param node: 节点 ''' self.__head = node if node: node.next = node# node存在,需要设置他的next区域指向他本身 #可以理解为链表中只有这一个节点 def is_empty(self): ''' 判断是否为空''' return self.__head is None def length(self): '''求长度''' # cur为游标,指向移动的游标,遍历节点 cur = self.__head# 创建指针 #count 计算节点数量 if self.is_empty(): return 0 # 空链表,直接返回0 count = 1 #count必须从1开始,因为节点的next等于头节点时,没有进入循环,count没有+1 #遍历节点 while cur.next != self.__head: # 这里不能使用cur,只能使用cur.next的原因是:创建游标的时候,就使用了cur等于头节点 # 详见length创建指针的代码 count +=1 cur = cur.next # 游标指向下一个节点§ return count def travel(self): ''' 遍历链表''' cur = self.__head if self.is_empty():# 为空,直接但会None,因为空链表进不去循环 return None while cur.next != self.__head: print(cur.elem,end = " ") cur = cur.next # 游标指向下一个节点 print(cur.elem,end=" ")# 退出循环的时候,需要再打印当前节点的值, # 因为最后一个节点的next,等于头节点,无法进入循环,因此无法打印 print("") def add(self,iterm): ''' 链表头部添加元素 最终要达到的效果,新节点的next指向原头部,然后头部节点指向新node 最后将尾节点的next指向头节点,需要遍历找到尾节点 :param iterm: 要插入的元素 ''' node = Node(iterm) # 数据元素封装为链表的节点 if self.is_empty(): self.__head=node node.next = node cur = self.__head while cur.next!=self.__head: cur = cur.next node.next = self.__head # 新节点的next指向原头部 self.__head = node # 头部指向新节点 cur.next = self.__head def append(self,iterm): ''' 尾部追加元素 :param iterm: :return: ''' '''先设置新的节点,遍历整个列表之后,将最后一个节点的指针指向新节点''' node = Node(iterm) '''如果链表是一个空列表,那么node就是None,没有next属性,因此需要考虑特殊情况''' 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 # 先将新节点的next指向头节点 cur.next = node# 再最后一个节点next指向node def insert(self,pos,iterm): ''' 随机插入元素 :param pos: 插入位置 :param iterm: 插入的元素 ''' if pos <=0:#小于0,相当于头部插入 self.add(iterm) elif pos >(self.length()-1):#大于列表总长度,相当于尾部添加 self.append(iterm) else: pre = self.__head # 可以理解为插入元素的游标,当前指向第一个节点 count = 0 while count < (pos - 1): # 判断让其指向pos的前一个节点 count += 1 pre = pre.next # 当循环退出之后,pre指向pos-1 node = Node(iterm) # 创建新的node节点 node.next = pre.next # pre当前指向的就是要插入的位置,因此先让node指向目标节点 pre.next = node # 然后修改pre的指针,指向node def remove(self,itrem): ''' 删除元素为elem的节点 可以使用两个游标节点,前一个和后一个保持一个节点的距离 删除节点的时候,让前一个节点指向后一个节点所指向的节点 :param itrem: 元素信息 ''' cur = self.__head if self.is_empty(): return pre = None while cur.next != self.__head: if cur.elem == itrem: # 元素相等的情况下,需要判断是否是头节点, # 因为刚开始pre是None,没有next属性 if cur == self.__head:#头节点 # 如果删除的是头节点,需要遍历找到尾节点,修改尾节点的next指向 wei = self.__head while wei.next != self.__head: wei = wei.next #跳出节点时,wei指向最后一个节点 self.__head = cur.next wei.next = self.__head else:#中间节点 pre.next = cur.next return # 这里代表整个头节点的结束,使用return退出整个函数 # 如果使用break,标识退出函数中的循环,下面的代码还会继续执行 else: pre = cur cur = cur.next #因为cur为尾节点的时候不进入循环,因此跳出循环体,cur才指向尾节点 if cur.elem == itrem : if cur ==self.__head: self.__head =None else: pre.next = cur.next def search(self,iterm): cur = self.__head # 如果是空列表,下面就无法去判断.next,因粗需要判断是否为空 if self.is_empty(): return False while cur.next != self.__head: # cur为None,意味着cur已经走到了链表的最后一位 if cur.elem == iterm: return True else: cur = cur.next if cur.elem == iterm:#因为最后一个节点未进入循环,因此没有进行比较,需要重新判断 return True return False if __name__ == '__main__': ll = ForLinkList() print("是否为空:", ll.is_empty()) print("长度:", ll.length()) ll.add(20) ll.append(100) ll.travel() ll.add(10) ll.travel() ll.insert(1,"haha") ll.travel() ll.remove(100) ll.travel() ll.remove(10) ll.travel() ll.remove(20) ll.travel() ll.remove("haha") print(ll.search(10)) *************run_result**************** 是否为空: True 长度: 0 20 100 10 20 100 10 haha 20 100 10 haha 20 haha 20 haha False
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。