python实现经典排序算法
以下排序算法最终结果都默认为升序排列,实现简单,没有考虑特殊情况,实现仅表达了算法的基本思想。
冒泡排序
内层循环中相邻的元素被依次比较,内层循环第一次结束后会将最大的元素移到序列最右边,第二次结束后会将次大的元素移到最大元素的左边,每次内层循环结束都会将一个元素排好序。
def bubble_sort(arr):
length = len(arr)
for i in range(length):
for j in range(length - i - 1):
if arr[j] > arr[j + 1]:
arr[j], arr[j + 1] = arr[j + 1], arr[j]
return arr
选择排序
每次内层循环都会得到一个当前最小的元素,并将其放到合适的位置。内层循环第一次结束后会将最小的元素交换到序列首位,第二次结束后会将第二小的元素交换到序列第二位,每次内层循环结束后都会将一个元素放在正确的顺序位置。
def selection_sort(arr):
length = len(arr)
for i in range(length):
min_index = i
for j in range(i + 1, length):
if arr[j] < arr[min_index]:
min_index = j
arr[i], arr[min_index] = arr[min_index], arr[i]
return arr
插入排序
类比玩扑克牌时理牌的思想,从第一个元素开始,假设它是已经排好序的。然后开始处理第二个元素,如果比第一个元素小,则将其放到第一个元素左边,否则放在其右边,那么现在前两个元素以及排好序了,之后再依次处理剩余的元素。
def insertion_sort(arr):
length = len(arr)
for i in range(1, length):
pre = i - 1
current_value = arr[i]
while pre >= 0 and arr[pre] > current_value:
arr[pre + 1] = arr[pre]
pre -= 1
arr[pre+1] = current_value
return arr
希尔排序
希尔排序就是将插入排序的改进版本。插入排序中每次逐步比较元素,而希尔排序中则是从一个较大的步数开始比较,最后减小到一步。
def shell_sort(arr):
length = len(arr)
gap = length // 2
while gap > 0:
for i in range(gap, length):
pre = i - gap
current_value = arr[i]
while pre >= 0 and arr[pre] > current_value:
arr[pre + gap] = arr[pre]
pre -= gap
arr[pre + gap] = current_value
gap = gap // 2
return arr
归并排序
先将序列前半部分排好序,再将序列后半部分排好序,之后再将这两部分合并得到最终的序列,具体实现为递归地将序列分为两部分,分别排序后再合并。
def merge(left, right):
result = []
while len(left) > 0 and len(right) > 0:
if left[0] < right[0]:
result.append(left.pop(0))
else:
result.append(right.pop(0))
if len(left) > 0:
result.extend(left[:])
if len(right) > 0:
result.extend(right[:])
return result
def merge_sort(arr):
if len(arr) < 2:
return arr
middle = len(arr) // 2
return merge(merge_sort(arr[:middle]), merge_sort(arr[middle:]))
快速排序
取一个元素,将比它小的元素都移到它左侧,将比它大的元素都移到它右侧,并递归地处理它左侧的序列和右侧的序列。
def partition(arr, left=None, right=None):
pivot = left
index = pivot + 1
for i in range(index, right + 1):
if arr[i] < arr[pivot]:
arr[i], arr[index] = arr[index], arr[i]
index += 1
arr[pivot], arr[index - 1] = arr[index - 1], arr[pivot]
return index - 1
def quick_sort(arr, left=None, right=None):
left = 0 if left is None else left
right = len(arr) - 1 if right is None else right
if left < right:
partition_index = partition(arr, left, right)
quick_sort(arr, left, partition_index - 1)
quick_sort(arr, partition_index + 1, right)
return arr
堆排序
首先构建一个最大堆,最大堆的性质是父节点的值总是大于其左右子节点的值,那么此时根节点的值是最大的,则将其移到序列的最右边。之后将堆中当前最后一个叶节点移到根节点上,因为这可能会不符合最大堆的性质,所以会进行调整,将它与其左右子节点中最大的值进行交换,则相当于将叶节点向下移动,交换过后如果还是不符合性质,则继续进行交换,直到符合性质后,此时的根节点的值就是当前堆中的最大值,将其取出放入序列中正确的位置后继续上述流程处理剩下的节点。
global length2
def heapify(arr, i):
left = 2 * i + 1
right = 2 * i + 2
largest = i
if left < length2 and arr[left] > arr[largest]:
largest = left
if right < length2 and arr[right] > arr[largest]:
largest = right
if largest != i:
arr[i], arr[largest] = arr[largest], arr[i]
heapify(arr, largest)
def build_max_heap(arr):
for i in range(len(arr) // 2, -1, -1):
heapify(arr, i)
def heap_sort(arr):
global length2
length2 = len(arr)
build_max_heap(arr)
for i in range(len(arr) - 1, 0, -1):
arr[0], arr[i] = arr[i], arr[0]
length2 -= 1
heapify(arr, 0)
return arr
计数排序
将序列中的元素按照其值放入相应的桶中,之后再按照桶的顺序取出即可,计数排序不需要比较操作。
def counting_sort(arr):
max_value = max(arr)
buckets = [0] * (max_value + 1)
index = 0
length = len(arr)
for i in range(length):
buckets[arr[i]] += 1
for j in range(max_value + 1):
while buckets[j] > 0:
arr[index] = j
index += 1
buckets[j] -= 1
return arr
桶排序
类别计数排序,构造很多桶,但每个桶中能放入值在特定范围内的元素,将序列中的元素按照要求放入各个桶中,再将每个桶中的元素进行排序,最后按照桶的顺序和各个桶中元素的顺序得到最终序列。
def bucket_sort(arr):
bucket_size = 5
max_value = max(arr)
min_value = min(arr)
bucket_num = (max_value - min_value) // bucket_size + 1
buckets = {i: [] for i in range(bucket_num)}
for i in range(len(arr)):
buckets[(arr[i] - min_value) // bucket_size].append(arr[i])
result = []
for i in range(bucket_num):
insertion_sort(buckets[i])
result.extend(buckets[i])
return result
基数排序
按照元素值的特定位进行排序,从低位到高位分别进行排序。
def radix_sort(arr):
max_value = max(arr)
max_digit = len(str(max_value))
dev = 1
mod = 10
result = arr[:]
for i in range(max_digit):
buckets = {i: [] for i in range(mod)}
for k in range(len(result)):
key = (result[k] % mod) // dev
buckets[key].append(result[k])
result = []
for j in range(mod):
result.extend(buckets[j])
dev *= 10
mod *= 10
return result
上述代码放在这里
参考
python实现经典排序算法的更多相关文章
- 经典排序算法总结与实现 ---python
原文:http://wuchong.me/blog/2014/02/09/algorithm-sort-summary/ 经典排序算法在面试中占有很大的比重,也是基础,为了未雨绸缪,在寒假里整理并用P ...
- 经典排序算法及python实现
今天我们来谈谈几种经典排序算法,然后用python来实现,最后通过数据来比较几个算法时间 选择排序 选择排序(Selection sort)是一种简单直观的排序算法.它的工作原理是每一次从待排序的数据 ...
- 十大经典排序算法(python实现)(原创)
个人最喜欢的排序方法是非比较类的计数排序,简单粗暴.专治花里胡哨!!! 使用场景: 1,空间复杂度 越低越好.n值较大: 堆排序 O(nlog2n) O(1) 2,无空间复杂度要求.n值较大: 桶排序 ...
- 经典排序算法的总结及其Python实现
经典排序算法总结: 结论: 排序算法无绝对优劣之分. 不稳定的排序算法有:选择排序.希尔排序.快速排序.堆排序(口诀:“快速.选择.希尔.堆”).其他排序算法均为稳定的排序算法. 第一趟排序后就能确定 ...
- python 经典排序算法
python 经典排序算法 排序算法可以分为内部排序和外部排序,内部排序是数据记录在内存中进行排序,而外部排序是因排序的数据很大,一次不能容纳全部的排序记录,在排序过程中需要访问外存.常见的内部排序算 ...
- 经典排序算法及总结(python实现)
目录 1.排序的基本概念和分类 排序的稳定性: 内排序和外排序 影响内排序算法性能的三个因素: 根据排序过程中借助的主要操作,可把内排序分为: 按照算法复杂度可分为两类: 2.冒泡排序 BubbleS ...
- python实现十大经典排序算法
Python实现十大经典排序算法 代码最后面会给出完整版,或者可以从我的Githubfork,想看动图的同学可以去这里看看: 小结: 运行方式,将最后面的代码copy出去,直接python sort. ...
- 用Python实现十大经典排序算法-插入、选择、快速、冒泡、归并等
本文来用图文的方式详细讲解了Python十大经典排序算法 —— 插入排序.选择排序.快速排序.冒泡排序.归并排序.希尔排序.插入排序.桶排序.基数排序.计数排序算法,想要学习的你们,继续阅读下去吧,如 ...
- 十大经典排序算法最强总结(含Java、Python码实现)
引言 所谓排序,就是使一串记录,按照其中的某个或某些关键字的大小,递增或递减的排列起来的操作.排序算法,就是如何使得记录按照要求排列的方法.排序算法在很多领域得到相当地重视,尤其是在大量数据的处理方面 ...
随机推荐
- GitLab的安装及使用
Gitlab环境部署 安装依赖包. sudo yum install -y curl policycoreutils-python openssh-server 设置SSH开机自启动并启动SSH服 ...
- 【JavaWeb】JSTL 标签库
JSTL 标签库 简介 JSTL(JSP Standard Tag Library),即 JSP 标准标签库.标签库是为了替换代码脚本,使得整个 jsp 页面变得更加简洁. JSTL 有五个功能不同的 ...
- 【LeetCode】365.水壶问题
题目描述 解题思路 思路一:裴蜀定理-数学法 由题意,每次操作只会让桶里的水总量增加x或y,或者减少x或y,即会给水的总量带来x或y的变化量,转为数字描述即为:找到一对整数a,b使得下式成立: ax+ ...
- C++ 中的 inline 详解
inline:是一个关键词,放在一个函数前面,说明这个函数是inline函数. inline函数是什么?inline有什么作用? 为了解答这个问题,我们首先要知道编译器是如何为我们工作的. 先看一段代 ...
- Docker学习笔记之使用Docker数据卷
Docker数据卷将数据存储到主机而非容器,多个容器需要共享数据时,常常使用数据卷. 1. 为容器设置数据卷(不指定主机目录) 2. 容器与主机之间.容器与容器之间共享数据卷(指定主机目录) 3. 使 ...
- (二)React Ant Design Pro + .Net5 WebApi:前端环境搭建
首先,你需要先装一个Nodejs,这是基础哦.如果没有这方面知识的小伙伴可以在园子里搜索cnpm yarn等关键字,内容繁多,此不赘述,参考链接 一. 简介 1. Ant Design Pro v5 ...
- Linux操作系统相关资料
玩转Linux操作系统 操作系统发展史 只有硬件没有软件的计算机系统被称之为"裸机",我们很难用"裸机"来完成计算机日常的工作(如存储和运算),所以必须用特定的 ...
- 两节锂电池充电芯片,和保护IC的接法
1.两节锂电池的充电电路:可以分为三种方式. 第一种,USB口的5V输入,使用一颗SOT23-6的升压IC,直接升压到8.4V.电流在1A以下.优点是成本最低,缺点是,没有锂电池充电控制逻辑,和锂电池 ...
- 安装git-macOS系统
通过homebrew安装Git 1.安装homebrew /usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/H ...
- 转 jmeter录制https请求
jmeter录制https请求 文章转自:https://www.cnblogs.com/zhengna/p/10180998.html 工具:Jmeter4.0 + Java1.8 需求:对某ht ...