最近在复习经典排序算法,自己用python也实现了一下,这里不会涉及到原理(因为网上方法已经很详细啦),就把函数贴上来,可以让大家自己试着运行下,再结合别处的原理也可以更好地理解它们的实现。

如果有错误请指出,或者优化的地方,谢谢啦。(´▽`)

1. 冒泡排序

冒泡排序是实现起来最简单的排序算法,时间复杂度是O(n^2),它的代码核心是两层嵌套的for循环,循环里一个判断数组相邻两个元素大小,如果不满足就交换。

冒泡排序有一个小的优化的点:如果在外层循环的一趟里没有交换任何元素,就说明排序完成了,就不需要再继续排了。所以也设置了一个flag判断。

代码如下:

"""

bubble sorting

"""

def bubble_sorting(array):

for i in range(len(array)-1):

flag = False

for j in range(len(array)-i-1):

if array[j]>array[j+1]:

flag = True

tmp = array[j]

array[j] = array[j+1]

array[j+1] = tmp

if not flag:

break

return array

array = [0,1,0,7,9,8,5,4,2,0]

print(bubble_sorting(array))

运行结果就是[0, 0, 0, 1, 2, 4, 5, 7, 8, 9]

2. 选择排序

选择排序也是一种时间复杂度是O(n^2)的稳定排序算法,它的核心思想就是每次遍历数组选出最小的放在左边 ,这样右边无序区越来越小,左边有序区越来越大。也是两层循环嵌套。

代码如下:

def select_sorting(array):

for i in range(len(array)):

min = array[i]

min_index = i

for j in range(i,len(array)):

if array[j]

min = array[j]

min_index = j

array[min_index] = array[i]

array[i] = min

return array

print(select_sorting(array))

运行结果 也是[0, 0, 0, 1, 2, 4, 5, 7, 8, 9]

3. 插入排序

插入排序跟上面两种排序算法比起来就算有点点绕了,它虽然也是需要两层循环,但是内层不再是遍历。插入排序要注意的是外层循环从第二个值开始,把第一个值当作是有序区。这样每一个新的值都会跟前面的有序区进行比较,如果小于前一个数就插到前面,一直到合适的位置为止。

def insert_sorting(array):

for i in range(1,len(array)):

j = i-1

while j >= 0 and array[j]>array[j+1]:

tmp = array[j+1]

array[j+1] = array[j]

array[j] = tmp

j -= 1

return array

print(insert_sorting(array))

7-28修改:之前还是觉得内层循环并不是插入排序,而是冒泡排序了,实际上并不需要每一个结果都要和上一个交换,因为插入排序应该是新的数和前面有序区的每一个数比较,如果仍然大于就把前面的数挪到后面,最后再插入新数。所以算法优化如下。

这里面的最后j+1其实也卡了我很久,但是后来想到:循环退出时一定不满足条件了,要么是j小于零,要么是终于找到了合适的位置。这让我想到一个小的脑筋急转弯:如果一个新的数比第二个数小,那么应该插入到哪里?答案是第二个。所以最后要把1加回来。

def insert_sorting1(array):

for i in range(1,len(array)):

j = i-1

tmp = array[i]

while j >= 0 and array[j]>tmp:

array[j+1] = array[j]

j -= 1

array[j+1] = tmp

return array

print(insert_sorting1([3,5,4,2,9,1,1,7,8,4]))

4. 快速排序

快速排序……卡了我很久很久,因为我一直在尝试用循环递推做,我……失败了。快排本身是一种很常用(超重要,面试也经常考的排序算法),它是一种“分治”的思想,就是要用递归的意思,接受了这一点再来写,就不会自己难为自己了。它始终选一个基准,一般是左边第一个,然后注意从右往左推,找到比他更小的就停止,然后从左往右推,找到比他更大的停止,然后判断下左右两个指针仍未相遇的话,就交换左右的值。此时左边都比基准小,右边都比基准大。再对左右两个子列表分别用这个方法,直到整个列表都有序。

接下来献上我很丑的代码:

def quick_sorting(start, end, array):

if start >= end:

return

min = start

max = end

pivot = array[min]

while start < end:

while start < end and array[end] > pivot:

end -= 1

while start < end and array[start] < pivot:

start += 1

if start < end:

array[start], array[end] = array[end], array[start]

quick_sorting(min, start-1, array)

quick_sorting(start+1,max,array)

return array

假如你并不需要保留重复的项,或者需要排序的列表没有重复项,那么可以用一个真正简单美丽的递归解决问题,其实这个就是刚才的算法的简化:

def quick_sort(array):

if len(array)<2:

return array

pivot = array[0]

left = [i for i in array if i < pivot]

right = [i for i in array if i > pivot]

return quick_sort(left)+[pivot]+quick_sort(right)

print(quick_sort(array))

7-25 修改:

刚刚想到一个方法可以使上面的快排保留重复的值,只要做一点小的变化:

def quick_sorting(array):

if len(set(array))<2:

return array

middle = array[0]

left = [i for i in array if i

pivot = [i for i in array if i == middle]

right = [i for i in array if i > middle]

return quick_sorting(left)+quick_sorting(pivot)+quick_sorting(right)

print(quick_sorting([9,9,1,8,5,2,3,3,7,14,2,2,2,2]))

所以以后偷懒的快排就可以这么写啦。

5. 堆排序(堆的基本操作)

我是按照小灰这一篇堆排序的文章写的代码,可以参考:

漫画:什么是二叉堆?(修正版)

总结起来,堆排序首先要理解二叉堆,大顶堆,小顶堆的概念,然后堆的基本操作有:插入(向上调整),删除(向下调整),调整二叉堆等。

希望大家有空可以读一下小灰的那篇文章~写得很清楚了,我这里就贴自己写得代码和用例吧。

# coding:utf-8

import sys

class HeapSorting():

def __init__(self,array):

self.arr = array

def insert(self,value):

child_index = len(self.arr)

self.arr.append(value) # add the new value at the end of array

tmp = self.arr[child_index]

while child_index >= 1 :

parent_index = (child_index - 1) // 2

if self.arr[parent_index] < tmp:

break

self.arr[child_index] = self.arr[parent_index]

child_index = parent_index

array[child_index] = tmp

return self.arr

def delete(self):

# delete the first value, make the last one the top

self.arr[0] = self.arr[-1]

del self.arr[-1]

parent_index = 0

child_index = parent_index*2+1

while child_index <= len(self.arr)-1:

child_index = parent_index * 2 + 2 if parent_index * 2 + 2 <= len(self.arr) - 1 and self.arr[

parent_index * 2 + 2] < self.arr[parent_index * 2 + 1] else parent_index * 2 + 1

if self.arr[parent_index] < self.arr[child_index]:

break

tmp = self.arr[parent_index]

self.arr[parent_index] = self.arr[child_index]

self.arr[child_index] = tmp

parent_index = child_index

child_index = parent_index*2+1

return self.arr

def down_adjust(self,parent_index):

child_index = parent_index*2+1

while child_index <= len(self.arr)-1:

child_index = parent_index * 2 + 2 if parent_index * 2 + 2 <= len(self.arr) - 1 and self.arr[

parent_index * 2 + 2] < self.arr[parent_index * 2 + 1] else parent_index * 2 + 1

if self.arr[parent_index] < self.arr[child_index]:

break

tmp = self.arr[parent_index]

self.arr[parent_index] = self.arr[child_index]

self.arr[child_index] = tmp

parent_index = child_index

child_index = parent_index*2+1

return self.arr

def adjust(self):

# start from the last non-leaf node

node = (len(self.arr)-2)//2

for i in range(node,-1,-1):

self.arr = self.down_adjust(i)

return self.arr

array = [7, 2, 6, 3, 9, 8, 5, 10, 12]

heap = HeapSorting(array)

heap_insert = heap.insert(1)

heap_delete = heap.delete() # delete the value on top of the heap

heap_adjust = heap.adjust()

print(heap_adjust)

上面的操作对于理解堆来说非常重要。

过两天还会补上正式的堆排序~就先写到这里(鞠躬)

python遍历数组冒泡排序_经典排序算法(冒泡排序,选择排序,插入排序,快速排序,堆排序)python实现...相关推荐

  1. 函数模板案例_利用函数模板封装一个排序的函数,可以对不同数据类型数组进行排序 排序规则从大到小,排序算法为选择排序 分别利用char数组和int数组进行测试

    案例描述: 利用函数模板封装一个排序的函数,可以对不同数据类型数组进行排序 排序规则从大到小,排序算法为选择排序 分别利用char数组和int数组进行测试 #include <iostream& ...

  2. Java经典排序算法:选择排序,动图演示排序过程

    Java经典排序算法:选择排序,动图演示排序过程 示意动图: public class Main {public static void main(String[] args) {new Main() ...

  3. 【排序算法】选择排序(Selection sort)

    选择排序(Selection sort)是一种简单直观的排序算法. 选择排序介绍 它的基本思想是: 首先在未排序的数列中找到最小(or最大)元素,然后将其存放到数列的起始位置:接着,再从剩余未排序的元 ...

  4. 【排序算法】选择排序(C语言)

    [排序算法]-- 选择排序 目录 一.选择排序的原理 二.选择排序的代码实现 三.选择排序的优化 1. 优化思路 2. 排序优化后问题 3. 优化代码的实现 四.选择排序的效率 一.选择排序的原理 ​ ...

  5. 排序---初级排序算法(选择排序、插入排序和希尔排序)

    写在前面的话: 一枚自学Java和算法的工科妹子. 算法学习书目:算法(第四版) Robert Sedgewick 算法视频教程:Coursera  Algorithms Part1&2 本文 ...

  6. 排序算法 | 直接选择排序,算法的图解、实现、复杂度和稳定性分析

    排序算法 | 直接选择排序,算法的图解.实现.复杂度和稳定性分析 目录 1.直接选择排序的原理 2.图解直接选择排序 3.算法代码实现 4.算法复杂度分析.稳定性分析 直接选择排序 1.直接选择排序的 ...

  7. 排序算法(3)选择排序

    排序算法(3)选择排序 原理:思想:两个变种(1)单侧选择:在一个无序数组中选择出每一轮中最大值(或最小值)元素,放到最前面或最后面(升序)(2)双向选择:在一个无序数组中选择出每一轮中最值元素,然后 ...

  8. 堆排序算法c语言筛选法,【排序】排序算法之选择排序

    排序算法之选择排序 罗朝辉(http://www.cppblog.com/kesalin) 转载请注明出处 排序是数据处理中经常使用的一种重要运算,在计算机及其应用系统中,花费在排序上的时间在系统运行 ...

  9. 选择排序算法流程图_常用排序算法之选择排序

    前两天给大家分享了冒泡排序和插入排序(没关注的同学,可以关注后查看历史消息),今天继续给大家分享另一种常用的排序算法--选择排序. 选择排序 选择排序和插入排序很相似,也区分已排序区间和未排序区间,选 ...

  10. 八大排序算法之选择排序算法

    文章目录 一:简单选择排序算法 1:思想 (1):概念 (2):举例验证 (3):上码 (3):时间复杂度和稳定性 二:堆排序 1:什么是堆 2:堆排序的原理(以升序序列为例) 3:堆排序算法的具体过 ...

最新文章

  1. iOS之runtime详解api(三)
  2. android考勤系统,Android端实现考勤管理系统
  3. python矩阵分解
  4. java 转xml 变成两根下划线_XStream将java对象转换为xml时,对象字段中的下划线“_”,转换后变成了两个...
  5. 201711月04日普及组 Array
  6. 2019年我总结的前端面试题
  7. Netty私有栈协议
  8. rabbitmq topic 收不到数据_RabbitMQ和Kafka到底怎么选?
  9. jdbc连接rac的oracle数据库
  10. 过年了,没买到票的可以过来看一看,12306抢票助手
  11. Android APP漏洞自动化静态扫描检测工具-Qark
  12. 【教程】创建活动报名二维码(活动报名/会议签到扫码,带微信手机号认证)
  13. 荣耀Magicbook安装黑苹果教程(OpenCore引导)
  14. 过来看!2021年物联卡资费标准,附:套餐价格+卡板价格
  15. FITC-STL,PL;荧光素标记马铃薯凝集素(STL,PL)
  16. 一般情况下的椭圆方程
  17. kafka之broker
  18. vue3 中使用腾讯地图
  19. [碎碎念]来谈谈写作这件事
  20. VS2015 Update 3正式版下载汇总

热门文章

  1. 初识php异步多线程扩展swoole
  2. 我的ubuntu8.04安装经验 (转)
  3. 全球75亿美元的网络安全险 会是保险业下一块金矿吗?
  4. cucumber_java从入门到精通(5)使用maven创建cucumber_java项目
  5. 年轻的力量!那些30岁前教你重新认识世界的牛人
  6. Silverlight实例教程 - Out of Browser在线更新和Silent安装
  7. Spring中的AOP在Advice方法中获取目标方法的参
  8. python 删除文件某一行
  9. linux lftp lftpget 命令简介
  10. mysql char varchar text 对比