[转载] Python算法
参考链接: Python使用散列的地址计算排序
排序
冒泡算法
arr = [1, 36, 7, 102, 54]
def BubbleSort(arr):
n = len(arr)
for i in range(0,n-1): #最后一位不用排了,所以是n-1
for j in range(0,n-1-i): #冒泡排序从后到前,不断减少范围
if arr[j]>arr[j+1]:
arr[j],arr[j+1]=arr[j+1],arr[j]
return arr
BubbleSort(arr)
print(arr)
选择排序
arr = [1, 36, 7, 102, 54]
# 扫描一遍,把最小的放在最小位置
def SelectSort(arr):
n = len(arr)
for i in range(0,n-1):
min_index = i #记录每一个位子
for j in range(i+1,n):
if arr[i] > arr[j]:
min_index = j
arr[i],arr[min_index] = arr[min_index],arr[i]
return arr
SelectSort(arr)
print(arr)
插入排序
arr = [1, 36, 7, 102, 54]
def InsertionSort(arr):
n = len(arr)
for i in range(1, n):
j = i - 1 # i是当前位, j是前一位
while j >= 0:
if arr[j] > arr[i]: # 前面一位大于后面一位
tem = arr[i]
arr[j + 1] = arr[j]
arr[j] = tem
j -= 1
return (arr)
归并排序
def merge_sort(S):
n = len(S)
if n < 2:
return S
mid = n // 2
S1 = S[0:mid]
S2 = S[mid:n]
merge_sort(S1)
merge_sort(S2)
merge(S1, S2, S)
def merge(S1, S2, S):
i = j = 0
while i + j < len(S):
if j == len(S2) or (i < len(S1) and S1[i] < S2[j]):
S[i + j] = S1[i]
i += 1
else:
S[i + j] = S2[j]
i += 1
return S
链表归并排序
class LinkedQueue():
def __init__(self, val):
self.val = val
self.next = None
def enqueue(self):
pass
def dequeue(self):
pass
class Solution:
S = LinkedQueue(None)
def merge(self, S1, S2, S):
while not S1.is_empty() and S2.is_empty():
if S1.first() < S2.first():
S.enqueue(S1.dequeue())
else:
S.enqueue(S2.dequeue())
while not S1.is_empty():
S.enqueue(S1.dequeue())
while not S2.is_empty():
S.enqueue(S2.dequeue())
def merge_sort(self, S):
n = len(S)
if n < 2:
return
S1 = LinkedQueue(None)
S2 = LinkedQueue(None)
while len(S1) < n//2:
S1.enqueue(S.dequeue())
while not S.is_empty():
S2.enqueue(S.dequeue())
self.merge_sort(S1)
self.merge_sort(S2)
快速排序
class Solution:
def quicksort(self, S):
if len(S) < 2:
return S
else:
pivot = S[len(S)//2] # 基准值
left = [i for i in S if i < pivot]
right = [i for i in S if i > pivot]
mid = [i for i in S if i == pivot]
return self.quicksort(left) + mid + self.quicksort(right)
if __name__ == '__main__':
arr = [57, 89, 65, 4, 5, 7, 32, 28, 456]
Solution = Solution()
print(Solution.quicksort(arr))
原地快速排序
def inplace_quick_sort(S, a, b):
if a >= b: return
pivot = S[b]
left = a
right = b-1
while left <= right:
while left <= right and S[left] < pivot:
left += 1
while left <= right and pivot < S[right]:
right -= 1
if left <= right:
S[left], S[right] = S[right], S[left]
left, right = left+1, right-1
S[left], S[b] = S[b], S[left]
inplace_quick_sort(S, a, left-1)
inplace_quick_sort(S, left+1, b)
return S
S = [1, 8, 6, 5, 7, 2]
print(inplace_quick_sort(S, 0, 5))
希尔排序
import random
source = [random.randrange(10000+i) for i in range(10000)]
step = int(len(source)/2)
while step>0:
for index in range(0, len(source)):
if index + step < len(source):
current_val = source[index]
if current_val > source[index+step]:
source[index], source[index+step] = source[index+step], source[index]
step = int(step/2)
else:
for index in range(1, len(source)):
current_val = source[index]
position = index
while position > 0 and source[position-1] > current_val:
source[position] = current_val
print(source)
基数排序
import random
def radixSort():
A = [random.randint(1, 9999) for i in range(10000)]
for k in range(4): # 4轮排序
s = [[] for i in range(10)] # 10个桶
for i in A:
s[i // (10 ** k) % 10].append(i)
A = [a for b in s for a in b]
return A
print(radixSort())
堆排序
def Max_Heapify(heap, heapsize, root):
'''
对一个父节点及其左右孩子节点调整;heap:list;heapsize:做数组最大限制,root:根节点位置
'''
left = 2 * root + 1 # 注意此处下标从0开始,下标为1开始时,公式为left = 2*root
right = left + 1
large = root
if left < heapsize and heap[large] < heap[left]:
large = left
if right < heapsize and heap[large] < heap[right]:
large = right
if root != large:
heap[root], heap[large] = heap[large], heap[root]
# 堆建立过程自下而上调整每个父节点及左右孩子
def Build_heap(heap, heapsize):
for root in range((heapsize - 1) // 2, -1, -1): # 表示求每个父节点位置
Max_Heapify(heap, heapsize, root)
# 堆排序
def Sort_heap(heap, heapsize, sortsize):
'''
heapsize:heap的长度
sortsize:未排序的数据个数
'''
Build_heap(heap, heapsize) # 排序前先建立一个最大堆
heap[0], heap[sortsize] = heap[sortsize], heap[0]
heapsize -= 1 # 最大值移到最后一位之后,将其从树中删除
sortsize -= 1 # 未排序个数减1
if sortsize != 0:
Sort_heap(heap, heapsize, sortsize)
计数排序
import random
def countingSort(alist, k):
n = len(alist)
b = [0 for i in range(n)]
c = [0 for i in range(k + 1)]
for i in alist:
c[i] += 1
for i in range(1, len(c)):
c[i] = c[i - 1] + c[i]
for i in alist:
b[c[i] - 1] = i
c[i] -= 1
return b
if __name__ == '__main__':
a = [random.randint(0, 100) for i in range(100)]
print(countingSort(a, 100))
桶排序
import random
class bucketSort(object):
def _max(self, oldlist): # 返回最大值
_max = oldlist[0]
for i in oldlist:
if i > _max:
_max = i
return _max
def _min(self, oldlist): # 返回最小值
_min = oldlist[0]
for i in oldlist:
if i < _min:
_min = i
return _min
def sort(self, oldlist):
_max = self._max(oldlist)
_min = self._min(oldlist)
s = [0 for i in range(_min, _max + 1)] # 初始值都是0的桶
for i in oldlist:
s[i - _min] += 1
current = _min
n = 0
for i in s:
while i > 0:
oldlist[n] = current
i -= 1
n += 1
current += 1
def __call__(self, oldlist):
self.sort(oldlist)
return oldlist
if __name__ == '__main__':
a = [random.randint(0, 100) for i in range(10)]
bucketSort()(a)
print(a)
二叉树遍历
前序遍历
# 前序遍历
def preorder(root):
if not root:
return []
return [root.val] + preorder(root.left) + preorder(root.right)
# 前序遍历的非递归实现 中左右
def preorderTraversal(root):
stack = [] # 右节点压入栈中,左节点递归
sol = []
curr = root
while stack or curr:
if curr:
sol.append(curr.val)
stack.append(curr.right)
curr = curr.left
else:
curr = stack.pop()
return sol
中序遍历
# 中序遍历的递归版本
def inorderTraversal(root):
if not root:
return []
return inorderTraversal(root.left) + [root.val] + inorderTraversal(root.right)
# 中序遍历的非递归版本
def inorderTraversal(self, root):
stack = [] # 把中间节点压入栈中
sol = []
curr = root
while stack or curr:
if curr:
stack.append(curr)
curr = curr.left
else:
curr = stack.pop()
sol.append(curr.val)
curr = curr.right
return sol
后序遍历
# 后序遍历的递归实现
def postorderTraversal(self, root): ##后序遍历
if not root:
return []
return self.inorderTraversal(root.left) + self.inorderTraversal(root.right) + [root.val]
# 后序遍历的非递归实现 左右中 [::-1] 中右左
def postorderTraversal(self, root): ## 后序遍历
stack = [] # 把左节点压入栈中,指针沿着右节点走
sol = []
curr = root
while stack or curr:
if curr:
sol.append(curr.val)
stack.append(curr.left)
curr = curr.right
else:
curr = stack.pop()
return sol[::-1]
广度优先遍历
# 广度优先递归实现
class Solution:
def levelOrder(self, root):
def helper(node, level):
if not node:
return
else:
sol[level-1].append(node.val)
if len(sol) == level: # 遍历到新层时,只有最左边的结点使得等式成立
sol.append([])
helper(node.left, level+1)
helper(node.right, level+1)
sol = [[]]
helper(root, 1)
return sol[:-1]
# 广度优先遍历的非递归实现
class Solution:
def levelOrder(self, root):
if not root:
return []
sol = []
curr = root # 树的遍历一般都会使用到栈这个结构
queue = [curr]
while queue:
curr = queue.pop(0)
sol.append(curr.val)
if curr.left:
queue.append(curr.left)
if curr.right:
queue.append(curr.right)
return sol
海量数据Top k算法 寻找最大的K个数
方法一:先对数据进行排序,然后取前K个 时间复杂度:O(k+n*logn)
方法二:维持一个最小堆,如果数值小于堆顶,就直接pass,如果大于堆顶,就直接替换堆顶,然后重新整理最小堆,整理一次的时间复杂度是logk 时间复杂度:O( k+(n-k)*logk )
方法三:类似quick select
# 海量数据Top k
def partition(seq):
qviot, seq = seq[0], seq[1:] # 选取并移除主元
right = [x for x in seq if x <= qviot] # 值较小的
left = [x for x in seq if x > qviot]
return right, qviot, left
def select(seq, k):
right, qviot, left = partition(seq)
m = len(right)
if m == k:
return right
if m < k:
right.append(qviot)
return right+select(left, k-m-1)
return select(right, k)
if __name__ == "__main__":
sel = [8,3,4,5,1,5,23,5,1,3,53,645,314,632,65,76,2,46,575,1,5]
print(select(sel, 5))
哈希表
什么是哈希函数? 哈希表(Hash table,也叫散列表),是根据关键码值(Key value)而直接进行访问的数据结构。也就是说,它通过把关键码值映射到表中一个位置来访问记录,以加快查找的速度。这个映射函数叫做散列函数,存放记录的数组叫做散列表。
常用的哈希函数有哪些?
直接定址法 取关键字或关键字的某个线性函数值为散列地址。 即 H(key) = key 或 H(key) = a*key + b,其中a和b为常数。除留余数法 取关键字被某个不大于散列表长度 m 的数 p 求余,得到的作为散列地址。 即 H(key) = key % p, p < m。数字分析法 当关键字的位数大于地址的位数,对关键字的各位分布进行分析,选出分布均匀的任意几位作为散列地址。 仅适用于所有关键字都已知的情况下,根据实际应用确定要选取的部分,尽量避免发生冲突。平方取中法 先计算出关键字值的平方,然后取平方值中间几位作为散列地址。 随机分布的关键字,得到的散列地址也是随机分布的。折叠法(叠加法) 将关键字分为位数相同的几部分,然后取这几部分的叠加和(舍去进位)作为散列地址。 用于关键字位数较多,并且关键字中每一位上数字分布大致均匀。随机数法 选择一个随机函数,把关键字的随机函数值作为它的哈希值。 通常当关键字的长度不等时用这种方法。
解决冲突的方法:
开放地址法:除了哈希函数得出地址可用,当出现冲突的时候其他地址一样可以使用再哈希法:按顺序规定多个哈希函数,每次查询时按顺序调用哈希函数链地址法:所有关键字哈希值都存储在同一线性链表中公共溢出区:一旦发生冲突全进入溢出表装填因子: a=(表中填入记录数)/(哈希表长度) a越小,冲突越小,0.75 比较合适
二叉树:
二叉树: 二叉树是每个节点最多有两个子树的树结构
二叉树有以下几个性质:TODO(上标和下标) 性质1:二叉树第i层上的结点数目最多为 2{i-1} (i≥1)。 性质2:深度为k的二叉树至多有2{k}-1个结点(k≥1)。 性质3:包含n个结点的二叉树的高度至少为log2 (n+1)。 性质4:在任意一棵二叉树中,若终端结点的个数为n0,度为2的结点数为n2,则n0=n2+1。 满二叉树,完全二叉树和二叉查找树
满二叉树 定义:高度为h,并且由2{h} –1个结点的二叉树,被称为满二叉树。 完全二叉树 定义:一棵二叉树中,只有最下面两层结点的度可以小于2,并且最下一层的叶结点集中在靠左的若干位置上。这样的二叉树称为完全二叉树。
特点:叶子结点只能出现在最下层和次下层,且最下层的叶子结点集中在树的左部。显然,一棵满二叉树必定是一棵完全二叉树,而完全二叉树未必是满二叉树。 二叉查找树 定义:二叉查找树(Binary Search Tree),又被称为二叉搜索树。设x为二叉查找树中的一个结点,x节点包含关键字key,节点x的key值记为key[x]。如果y是x的左子树中的一个结点,则key[y] <= key[x];如果y是x的右子树的一个结点,则key[y] >= key[x]。 B树: B 树可以看作是对2-3查找树的一种扩展,即他允许每个节点有M-1个子节点。
根节点至少有两个子节点每个节点有M-1个key,并且以升序排列位于M-1和M key的子节点的值位于M-1 和M key对应的Value之间其它节点至少有M/2个子节点
下图是一个M=4 阶的B树: B+树: B+树是对B树的一种变形树,它与B树的差异在于:
有k个子结点的结点必然有k个关键码;非叶结点仅具有索引作用,跟记录有关的信息均存放在叶结点中。树的所有叶结点构成一个有序链表,可以按照关键码排序的次序遍历全部记录。 B+ 树的优点在于:B+树的叶子结点都是相链的,因此对整棵树的便利只需要一次线性遍历叶子结点即可。而且由于数据顺序排列并且相连,所以便于区间查找和搜索。而B树则需要进行每一层的递归遍历。相邻的元素可能在内存中不相邻,所以缓存命中性没有B+树好。由于B+树在内部节点上不包含数据信息,因此在内存页中能够存放更多的key。 数据存放的更加紧密,具有更好的空间局部性。因此访问叶子节点上关联的数据也具有更好的缓存命中率。
剖析2:为什么B+树比B树更适合做系统的数据库索引和文件索引 1)B+树的磁盘读写代价更低 因为B+树内部结点没有指向关键字具体信息的指针,内部结点相对B树小 2)B+树的查询更加稳定 因为非终端结点并不是指向文件内容的结点,仅仅是作为叶子结点的关键字索引,因此所有的关键字查询都会走一条从根节点到叶子结点的路径。即s所有关键字查询的长度是一样的,查询效率稳定。
[转载] Python算法相关推荐
- [转载] python价值算法_PangRank算法原理及其Python实现
参考链接: 页面排名算法Page Rank和Python实现 文章目录 算法来源 早期搜索引擎采用分类目录的方法,通过人工进行网页分类,并整理出高质量的网页. 后来,随着网页的增多,人工分类已经不现实 ...
- 这可能是史上最全的Python算法集!
来源 | CSDN(ID:CSDNnews ) 本文是一些机器人算法(特别是自动导航算法)的Python代码合集. 其主要特点有以下三点:选择了在实践中广泛应用的算法:依赖最少:容易阅读,容易理解每个 ...
- python代码大全下载-最全Python算法实现资源汇总!
原标题:最全Python算法实现资源汇总! 整理 | Rachel 责编 | Jane 出品 | Python大本营(ID:pythonnews) [导语]数据结构与算法是所有人都要学习的基础课程,自 ...
- [转载] python常用库
参考链接: Python–新一代语言 转载至:https://www.cnblogs.com/jiangchunsheng/p/9275881.html 今天我将介绍20个属于我常用工具的Python ...
- python常用代码入门-最全Python算法实现资源汇总!
原标题:最全Python算法实现资源汇总! 整理 | Rachel 责编 | Jane 出品 | Python大本营(ID:pythonnews) [导语]数据结构与算法是所有人都要学习的基础课程,自 ...
- 化学人学python有前途吗-转载:python之蟒开启理论计算化学的新时代
转载:python之蟒开启理论计算化学的新时代 (2014-01-23 23:04:00) 标签: python gaussian python之蟒开启理论计算化学的新时代 就像iphone和andr ...
- python算法动画_这可能是史上最全的Python算法集!
来源 | CSDN(ID:CSDNnews ) 本文是一些机器人算法(特别是自动导航算法)的Python代码合集. 其主要特点有以下三点:选择了在实践中广泛应用的算法:依赖最少:容易阅读,容易理解每个 ...
- [转载]Python兵器谱
转载自:http://www.52nlp.cn/python-网页爬虫-文本处理-科学计算-机器学习-数据挖掘 曾经因为NLTK的缘故开始学习Python,之后渐渐成为我工作中的第一辅助脚本语言,虽然 ...
- python源码大全-最全Python算法实现资源汇总!
原标题:最全Python算法实现资源汇总! 整理 | Rachel 责编 | Jane 出品 | Python大本营(ID:pythonnews) [导语]数据结构与算法是所有人都要学习的基础课程,自 ...
最新文章
- 企业如何应对BT传输
- spring 多租户_使用Spring Security的多租户应用程序的无状态会话
- 《Scikit-Learn与TensorFlow机器学习实用指南》第8章 降维
- Java优雅的记录日志:log4j实战篇
- Pyqt+QRcode 生成 识别 二维码
- php 小程序发送公众号的模板消息
- SSO单点登录系统的搭建——Keycloak
- Java web 集成使用QQ互联
- Arduino_Core_STM32---pinMode()实现分析
- python--数据导入--read_excel
- windows文字转语音示例
- 安全架构--13--企业资产管理体系建设总结
- python歌词统计_Python大佬分析了15万歌词,告诉你民谣歌手们到底在唱什么
- W/View: requestLayout() improperly called by androidapp:id/toolbar_title} during second layout pass:
- 开源传感器网络平台OpenWSN
- SDN网络下有哪些SDN交换机选择?
- 戏如人生,人生如戏!
- 移动之过之过还是UC、GGlive,vfun之过?——cmwap无限流量卡价格飚升背后的故事
- HUAWEIWATCH GT3有哪些功能?华为新款手表测评
- 法国学术会议申根签证办理(因私)
热门文章
- 主要知识产权(专利权,著作权,商标权)的申请与保护
- 【w3cschool】Linux命令简单复习
- 【特别版】计算机哲学对学习生活借鉴的几个例子
- python语言源程序文件类型_Python语言源程序文件的文件类型是__________。
- SQL Server高级查询之常见数据库对象(索引)第五章节
- 有向图的传递闭包实现三种实现(Warshall+DFS+BFS)
- 网络地址转换协议NAT详解
- UnityShader11:纹理属性
- HDU 5980 2016ICPC大连 J: Find Small A
- [Python] 生成迭代器 iter() 函数