# a+b+c =1000 a²+b²=c²(abc均为自然数),求出abc的组合 for a in range(0,1001): for b in range(0,1001): for c in range(0,1001): if a + b + c == 1000 and a**2 + b**2 == c ** 2: print(a,b,c) for a in range(0,1001): for b in range(0,1001): c = 1000 - a - b if a + b + c == 1000 and a**2 + b**2 == c**2: print(a,b,c) a = 5 b = 6 c = 10 n = 10 for i in range(n): for j in range(n): x = i*i y = j*j z = i*j for k in range(n): w = a*k +45 v = b*b d = 33 #实例化一个空列表 然后将0-1000范围的书添加到列表中 4个方法 def txt1(): a = [] for i in range(1000): a = a +[ i] return a def text2(): a = [] for i in range(1000): a.append(i) return a def txt3(): return [i for i in range(1000)] def txt4(): a = list(range(1000)) return a from timeit import Timer if __name__ == '__main__': timer = Timer('txt1()','from __main__ import txt1') t1 = timer.timeit(1000) print(t1) timer = Timer('txt2()','from __main__ import txt2') t2 = timer.timeit(1000) print(t2) timer = Timer('txt3()','from __main__ import txt3') t3 = timer.timeit(1000) print(t3) timer = Timer('txt4()','from __main__ import txt4') t4 = timer.timeit(1000) print(t4)
数据结构:
如何用两个队列实现一个栈
单链表
链表是由节点组成.并且每一个节点对应的内存空间不是连续开辟,可以解决数组,列表插入,删除元素产生的数据迁移
节点:
item:储存的是数据
next:存储的是下一个节点的地址
链表:
head:保存的是第一个节点的地址,head的指向一般不会发生改变.要永远指向第一个节点的地址
cur 当前节点的地址 ,pre前一个节点的地址
有序链表:排序
二叉树:
根节点
root的引用指向跟节点
只有两个分叉
插入节点
排序二叉树: 插入的节点,依次和原树中的节点对比,小则插入左侧,大则插入右侧
深度遍历:
前序:根左右
中序:左根右 遍历出的就是一个有序的节点
后序:左右根
算法:
二分查找:必须是在有序的前提
选择:
冒泡:
插入:
希尔:插入就是一个增量为1的希尔排序
快速排序:
使用不同的形式组织数据,在基于查询时的时间复杂程度是不一样的,因此认为算法是为了解决实际问题而设计的,
数据结构是算法需要处理问题的载体
# ●Stack()创建一个空的新栈。 它不需要参数,并返回-个空栈。 # ●push(item)将一 个新项添加到栈的顶部。它需要item做参数并不返回任何内容。 # ●pop()从栈中删除顶部项。它不需要参数并返回item. 栈被修改. # ●peek()从栈返回顶部项,但不会删除它。不需要参数。不修改栈。 # ●isEmpty()测试栈是否为空。不需要参数,并返回布尔值。 # ●size()返回栈中的item数量.不需要参数,并返回一个整数。 class Stack(): def __init__(self): self.items =[] def push(self,items): self.items.append(items) def pop(self): return self.items.pop() def peek(self): return len(self.items) -1 def isempty(self): return self.items ==[] def size(self): return len (self.items) stack = Stack() stack.push(1) stack.push(2) stack.push(3) print(stack.peek()) print(stack.isempty()) print(stack.size()) print(stack.pop()) print(stack.pop()) print(stack.pop()) #先进先出
# ●Queue() 创建-一个空的新队列。它不需要参数,并返回一一个空队列。 # ●enqueue(item) 将新项添加到队尾。它需要 item作为参数,并不返回任何内容。 # ●dequeue() 从队首移除项。它不需要参数并返回item。队列被修改。 # ●isEmpty()查看队列是否为空。它不需要参数,并返回布尔值。 # ●size() 返回队列中的项数。它不需要参数,并返回- -个整数。 class Qenche(): def __init__(self): self.item = [] def enquene(self,item): self.item.insert(0,item) def dequen (self): return self.item.pop() def isEmpty(self): return self.item ==[] def size(self): return len(self.item) q = Qenche() q.enquene(1) q.enquene(2) q.enquene(3) print(q.dequen()) print(q.dequen()) print(q.dequen()) #案例:烫手的山芋 # ■烫手山芋游戏介绍: 6个孩子围城-一个圈, 排列顺序孩子们自己指定。第- -个孩子手里有一一个烫手的山芋,需要在计时器计时1秒后将山芋传递给下-一个孩 # 子,依次类推。规则是,在计时器每计时7秒时,手里有山芋的孩子退出游戏。该游戏直到剩下一一个孩子时结束,最后剩下的孩子获胜。请使用队列实现 # 该游戏策略,排在第几个位置最终会获胜。 Kids = ['A','B','C','D','E','F','G','H','I','J','K'] #多少个人都是第五个人获胜 queue = Qenche() for kid in Kids: queue.enquene(kid) while queue.size() > 1: for i in range(6): #没循环一次 山芋传递一次 手里有山芋的孩子永远在对头位置 kid = queue.dequen() queue.enquene(kid) queue.dequen() print("获胜的选手是",queue.dequen())
# ●Deque()创建一 个空的新deque。 它不需要参数,并返回空的deque. # ●addFront(item)将一 个新项添加到deque的首部。它需要item参数并不返回任何内容。 # ●addRear(item) 将-个新项添加到deque的尾部。它需要item参数并不返回任何内容。 # ●removeFront() 从deque中删除首项。它不需要参数并返回item。deque被修改。 # ●removeRear() 从deque中删除尾项。它不需要参数并返回item。deque 被修改。 # ●isEmpty()测试deque是否为空。它不需要参数,并返回布尔值。 # ●size()返回deque中的项数。它不需要参数,并返回-一个整数。 class Deque(): def __init__(self): self.items = [] def addFront(self,items): self.items.insert(0,items) def addRear(self,items): self.items.append(items) def removeFront(self): return self.items.pop() def removeRear(self): return self.items.pop(0) def isEmpty(self): return self.items ==[] def size(self): return len(self.items) q = Deque() q.addFront(1) q.addFront(2) q.addFront(3) q.addFront(4) print(q.removeFront()) print(q.removeFront()) #先进先出 print(q.removeFront()) print(q.removeFront()) print(q.removeRear()) #先进后出 print(q.removeRear()) # ●双端队列应用案例:回文检查 # ■回文是一个字符串,读取首尾相同的字符,例如,radar toot madam。 def ishuiwen(s): ex = True q = Deque() for ch in s: q.addFront(ch) while q.size() > 1: if q.removeFront() != q.removeRear(): ex = False break return ex print(ishuiwen("xxqwreqtgqafafs"))
# is_ empty(): 链表是否为空 # length():链表长度 # travel():遍历整个链表 # add(item):链表头部添加元素 # append(item):链表尾部添加元素 # insert(pos, item):指定位置添加元素 # remove(item):删除节点 # search(item):查找节点是否存在 class Node(): def __init__(self,item): self.item = item self.next = None class Link(): def __init__(self): #构造出一个空的链表 head存储的只能是空或者一个节点的地址 self._head = None def add(self,item): node = Node(item) node.next = self._head self._head = node # def travel(self): # print(self._head.item) # print(self._head.next.item) def travel(self): #head在链表创建好之后一定是不可变 cur = self._head while cur: print(cur.item) cur = cur.next def isEmpty(self): return self._head ==None def size(self): cur = self._head count = 0 while cur: count +=1 cur = cur.next return count def append(self,item): node = Node(item) #链表是空的直接添加 if self._head ==None: self._head = node return cur = self._head pre = None while cur: pre = cur cur = cur.next pre.next = node def search(self,item): find = False cur = self._head while cur: if cur.item: find = True break cur = cur.next return find def insert(self,pos,item): node = Node(item) pre = None cur = self._head for k in range(pos): pre = cur cur = cur.next pre.next = node node.next = cur def remove(self,item): cur = self._head pre = None # if cur.item ==item: self._head = cur.next return while cur: pre =cur cur = cur.next if cur.item ==item: pre.next = cur.next return link = Link() link.add(3) link.add(4) link.add(5) link.add(6) link.add(7) link.travel() link.append(8) link.append(9) link.search(2,) print(link.isEmpty()) print(link.size()) print(link.search)
#如何使用两个队列实现一个栈 class Queue(): def __init__(self): self.items = [] def enqueue(self,item): self.items.insert(0,item) def dequeue(self): return self.items.pop() # def tarvel(self): # for item in self.items: # print(item) def size(self): return len(self.items) #如何使用两个队列实现一个栈 alist = [1,2,3,4,5,6,7,8,9] q1 = Queue() for i in alist: q1.enqueue(i) q2 = Queue() while q1.size() > 0: #将q1中n-1个值取出来放到q2中 while q1.size() > 1: item = q1.dequeue() q2.enqueue(item) print(q1.dequeue()) q1,q2 = q2,q1 # q = Queue() # q.enqueue(1) # q.enqueue(2) # q.enqueue(3) # q.dequeue() #如何实现将单链表倒置 class Node(): def __init__(self,item): self.item = item self.next = None class Link(): def __init__(self): self._head = None def append(self,item): node = Node(item) if self._head ==None: self._head =node return cur = self._head pre = None while cur: pre = cur cur = cur.next pre.next = node def tarvel(self): cur = self._head while cur: print(cur.item) cur = cur.next def remove(self,item): cur =self._head pre = None if cur.item ==item: self._head =cur.next return while cur: pre = cur cur = cur.next if item == cur.item: pre.next = cur.next return def reverse(self): cur = self._head pre = None next_node = cur.next while cur: cur.next = pre pre = cur cur = next_node if cur: next_node = cur.next self._head = pre Link =Link() Link.append(1) Link.append(2) Link.append(3) Link.append(4) Link.append(5) Link.append(6) Link.append(7) Link.remove(1) Link.tarvel()
#二叉树 # 根节点 # 叶子结点 # 左叶子结点 # 右叶子结点 # 树的层级 # 树的高度 #二叉树的遍历 # 广度优先 # 一层一层的进行遍历 # 深度优先 #前序:根左右 1245367 #中序:左跟右 4251637 #后续:左右根 4526731 # 1 # 2 3 # 4 5 6 7 #二叉树的节点插入 class Node(): def __init__(self,item): self.item = item self.left = None self.right = None class Tree():#空树 def __init__(self): self.root = None def addNOde(self,item): node = Node(item) #如果插入第一个节点的情况 if self.root ==None: self.root =node return cur = self.root #根节点 q = [cur] #列表元素是我们进行遍历判断的节点 while q: newp = q.pop(0) if newp.left == None: #如果二叉树左侧节点是空就添加赋值 newp.left = node return else: q.append(newp.left) #不为空添左节点加到链表当中 if newp.right ==None: #如果二叉树右侧是空就添加赋值 newp.right = node return else: q.append(newp.right)#不为空右节点添加到链表当中 def travel(self): cur = self.root q = [cur] while q: nd = q.pop(0) print(nd.item) if nd.left: q.append(nd.left) if nd.right: q.append(nd.right) def forwoar(self,root): #前序 根左右 if root == None: return print(root.item) self.forwoar(root.left) self.forwoar(root.right) def middle(self,root):#前序 左根右 if root == None: return self.middle(root.left) print(root.item) self.middle(root.right) def back(self,root): #后续 左右根 if root == None: return self.back(root.left) self.back(root.right) print(root.item) node = Node(3) tree= Tree() tree.addNOde(1) tree.addNOde(2) tree.addNOde(3) tree.addNOde(4) tree.addNOde(5) tree.addNOde(6) tree.addNOde(7) # tree.travel() tree.forwoar(tree.root) tree.middle(tree.root) tree.back(tree.root) #二叉树 and 排序 二叉树 #乱序数据插入的时候 要遵循一个准则: #后续插入的数值 如果比根节点小 插入根节点的左侧 否则插入到根节点的右侧 class Nodeto(): def __init__(self,item): self.item = item self.left = None self.right = None class SortTree(Tree): def __init__(self): self.root = None def add(self,item): cur = self.root if self.root ==None: self.root = node return while cur: #向右侧插入 if item > cur.item: if cur.right ==None: cur.right = node return else: cur = cur.right #想左插入 else: if cur.left == None: cur.left = node return else: cur = cur.left tree = SortTree() alist = [3,5,6,3,4,2,54,3,4,23,4,3,4,2] for i in alist: tree.add(i) tree.forwoar(tree.root)
# #二分查找 # ●二分查找: -定是基于有序集合的查找 # ■有序列表对于我们的实现搜索是很有用的。在顺序查找中,当我们与第一个元素进行比较时,如果第一 个元素不是我们要查找的,则最多还有n-1个元素 # 需要进行比较。二分查找则是从中间元素开始, 而不是按顺序查找列表。如果该元素 是我们正在寻找的元素,我们就完成了查找。如果它不是, 我们可 # 以使用列表的有序性质来消除剩余元素的一半。如果我们正在查找的元素大于中间元素,就可以消除中间元素以及比中间元素小的一半元素。如果该元素 # 在列表中,肯定在大的那半部分。然后我们可以用大的半部分重复该过程,继续从中间元素开始,将其与我们正在寻找的内容进行比较。 alist = [1,2,3,4,5,6,7,8,9,] def find(alist,item): find = False mid = len(alist) // 2 #中间元素 first = 0 last = len(alist) -1 while first <= last: mid = (first + last) //2 if alist[mid] < item: ##去除中间的元素去右侧寻找 first = mid + 1 elif alist[mid] > item: last = mid -1 else: find = True return find print(find(alist,5))
#冒泡排序 # def sort0(alist): # for i in range(len(alist)-1): # if alist[i] > alist[i+1]: # alist[i],alist[i+1] = alist[i+1],alist[i] # return alist # #主键将乱序的最大值找出防止在乱序列的尾部 # def sort(alist): # for j in range(len(alist)-1): # for i in range(len(alist)-1-j): # if alist[i] > alist[i+1]: # alist[i],alist[i+1] = alist[i+1],alist[i] # return alist # alist = [3,8,7,4,9,2] # print(sort(alist)) #选择排序 def sort(alist) : for j in range(0, len(alist)-1) : max_index = 0 #最大值的下标 for i in range(1, len(alist)-j): if alist [max_index] < alist[i]: max_index = i alist[len(alist)-1-j],alist[max_index] = alist [max_index], alist[len(alist)-1-j] return alist alist = [3,8,7,4,9,2] print(sort(alist))
#插入排序 #并有序子集中元案的个数,还可以表示下标 i=1 #alist[iJ乱序子集中的第一个元案 #alist[i-I]有序子集中的最后一个元素 if alist[i] < alist[i-1]:#乱序子集中的第一个元素值小于有序子集中的最后一个元素的值,交赖位置 alist[i],alist[i-1] = alist[i-1], alist[i] else: pass i +=1 i = 2 while i > 0 : if alist[i] < alist[i-1]: alist[i],alist[i-1] = alist[i-1],alist[i] i -= 1 else: break #完整代码 def sort(alist): for i in range(1,len(alist)): while i > 0: if alist[i] < alist[i-1]: alist[i],alist[i-1] = alist[i-1],alist[i] i -=1 else: break return alist alist = [3,5,6,7,9,1] print(sort(alist))
# -希尔排序(Shell Sort)是插入排序的一种。也称缩小增量排序,是直接插入排序算法的一种更高效的改进版本,该方法的基本思想 # 是:先将整个待排元素序列分割成若干个子序列(由相隔某个“增量(gap) ”的元素组成的)分别进行直接插入排序,然后依次缩减增量 # 再进行排序,待整个序列中的元素基本有序(增量足够小)时,再对全体元素进行一次直接插入排序。 因为直接插入排序在元素基本有序 # 的情况下(接近最好情况),效率是很高的, 因此希尔排序在时间效率比直接插入排序有较大提高。 # 希尔排序 # gap # 增量值 # 拆分出来的数组 # 插入排序就是增量为1的希尔排序 def sort(alist) : gap = len(alist)//2 #初识gap while gap >= 1: for i in range (gap, len(alist)): while i > 0: if alist[i] < alist[i- gap]: alist[i],alist[i-gap] = alist[i-gap], alist[i] i -= gap else: break gap //= 2 return alist alist = [2,5,7,9,0,8,6,3] print(sort(alist))
#快速排序 # 1.指定一个基数(乱序中的第一个数据值) # 2.将比基数小的数据放置在基数的左侧,比基数大的数放在基数的右侧 # 3.从右边开始偏移hegh def sort(alist,start,end): low = start high = end #递归结束的条件 if low > high: return #基准:最左侧的数值 mid = alist[low] #low和high的关系只能是小于,当等于的时候就要填充mid了 while low < high: while low < high: if alist[high] > mid: high -= 1 else: alist[low] = alist[high] break while low < high: if alist[low] < mid: low += 1 else: alist[high] = alist[low] break #当low和high重复的时候,将mid填充 if low == high: alist[low] = mid #or alist[high] = mid break #执行左侧序列 sort(alist,start,high-1) #执行右侧序列 sort(alist,low+1,end) return alist alist = [6,1,2,7,9,3,4,5,10,8] print(sort(alist,0,len(alist)-1))
def merge_sort(alist): n = len(alist) #结束递归的条件 if n <= 1: return alist #中间索引 mid = n//2 left_li = merge_sort(alist[:mid]) right_li = merge_sort(alist[mid:]) #指向左右表中第一个元素的指针 left_pointer,right_pointer = 0,0 #合并数据对应的列表:该表中存储的为排序后的数据 result = [] while left_pointer < len(left_li) and right_pointer < len(right_li): #比较最小集合中的元素,将最小元素添加到result列表中 if left_li[left_pointer] < right_li[right_pointer]: result.append(left_li[left_pointer]) left_pointer += 1 else: result.append(right_li[right_pointer]) right_pointer += 1 #当左右表的某一个表的指针偏移到末尾的时候,比较大小结束,将另一张表中的数据(有序)添加到result中 result += left_li[left_pointer:] result += right_li[right_pointer:] return result alist = [3,8,5,7,6] print(merge_sort(alist))