排序算法之NB三人组
快速排序
思路:
例如:一个列表[5,7,4,6,3,1,2,9,8],
1.首先取第一个元素5,以某种方式使元素5归位,此时列表被分为两个部分,左边的部分都比5小,右边的部分都比5大,这时列表变成了[2,1,4,3,5,6,7,9,8]
2.再对5左边进行递归排序,取5左边部分的第一个元素2,使2归位,这时5左边的部分变成了[1,2,4,3]
3.2归位后再对2右边5左边的部分即[4,3]进行排序,然后整个列表中5左边的部分就完成了排序
4.再使用递归方法对5右边的部分进行递归排序,直到把列表变成有序列表
列表就变成有序列表了.
代码实现:
def _quick_sort(data,left,right):
if left < right:
mid=partition(data,left,right)
_quick_sort(data,left,mid-1)
_quick_sort(data,mid+1,right)
def partition(li,left,right):
print("befor sort:",li)
tmp=li[left]
while left <right:
while left <right and tmp < li[right]:
right -=1
li[left]=li[right]
while left <right and li[left] < tmp:
left += 1
li[right]=li[left]
li[left]=tmp
print("after sort:",li)
return left
def quick_sort(li):
_quick_sort(li,0,len(li)-1)
li=[5,7,4,6,3,1,2,9,8]
print(quick_sort(li))
打印结果:
befor sort: [5, 7, 4, 6, 3, 1, 2, 9, 8]
after sort: [2, 1, 4, 3, 5, 6, 7, 9, 8]
after sort: [1, 2, 4, 3, 5, 6, 7, 9, 8]
after sort: [1, 2, 3, 4, 5, 6, 7, 9, 8]
after sort: [1, 2, 3, 4, 5, 6, 7, 9, 8]
befor sort: [1, 2, 3, 4, 5, 6, 7, 9, 8]
befor sort: [1, 2, 3, 4, 5, 6, 7, 9, 8]
after sort: [1, 2, 3, 4, 5, 6, 7, 8, 9]
快排的最坏情况:
如果一个列表完全是倒序的,递归的次数为最大,等于len(li)*log(len(li))
此时可以随机取列表中的一个元素进行排序.
堆排序
树与二叉树
树是一种数据结构,比如linux的目录是呈倒树状结构
树是一种可以递归定义的数据结构
树是由n个节点组成的集合
如果n=0,那这是一棵空树
如果n>0,那存在1个节点作为树的根节点,其他节点可以分为m个集合,每个集合本身又是一棵树
关于树的一些概念
根节点 例如 A节点
叶子节点 例如 B,C,H,I,P,Q等不再分叉的节点
树的深度(高度) 例如 上图中的树共有4层,所以这棵树的深度为4
子节点/父节点 例如 A,D,E,J等为父节点,B,C,H,I,P为子节点
子树
二叉树:度不超过2的树(节点最多有两个叉)
两种特殊的二叉村
满二叉树:除了叶子节点,所有节点都有两个子节点,且所有叶子节点的深度都相同
完全二叉树:从满二叉树的后边拿走几个节点,就变成了完全二叉树,中间不能缺少节点
堆排序
大根堆:一棵完全二叉树,满足任一节点都比其子节点大
小根堆:一棵完全二叉树,满足任一节点都比其子节点小
假设节点的左右子树都是堆,但自身不是堆,
当根节点的左右子树都是堆时,可以通过一次向下的调整来将其变换成一个堆
构造堆
首先有这样一棵二叉树,
先调整最后一个小子树,把大的元素放到这个小子树的顶部,使小子树变成一个堆
再对倒数第二个小子树进行调整,使这个小子树变成一个堆
再对倒数第三个小子树进行调整,使这个小子树变成一个堆
对这棵树中的每一个小子树都进行调整,最后这棵二叉树就变成了一个大根堆.
堆排序过程:
1.建立堆
2.得到堆顶元素,为最大元素
3.去掉堆顶,将堆最后一个元素放到堆顶,此时可通过一次调整重新使堆有序
4.这时堆顶元素为堆中的第二大元素
5.重复3步骤,直到堆变空
代码实现:
def sift(li,left,right):
i=left
j= 2 *i +1
tmp=li[left]
while j <=right:
if j < right and li[j] < li[j+1]:
j += 1
if tmp < li[j]:
li[i] = li[j]
i = j
j = 2 * i + 1
else:
break
li[i] = tmp
def heap_sort(li):
n = len(li)
for i in range(n//2-1 , -1 ,-1):
sift(li,i,n-1)
print(li)
for j in range(n-1,-1,-1):
li[0],li[j]=li[j],li[0]
sift(li,0,j-1)
print(li)
li=[2,9,7,8,5,0,1,6,4,3]
sift(li,0,len(li)-1)
heap_sort(li)
print(li)
输出打印为:
[9, 8, 7, 6, 5, 0, 1, 2, 4, 3]
[9, 8, 7, 6, 5, 0, 1, 2, 4, 3]
[9, 8, 7, 6, 5, 0, 1, 2, 4, 3]
[9, 8, 7, 6, 5, 0, 1, 2, 4, 3]
[9, 8, 7, 6, 5, 0, 1, 2, 4, 3]
[8, 6, 7, 4, 5, 0, 1, 2, 3, 9]
[7, 6, 3, 4, 5, 0, 1, 2, 8, 9]
[6, 5, 3, 4, 2, 0, 1, 7, 8, 9]
[5, 4, 3, 1, 2, 0, 6, 7, 8, 9]
[4, 2, 3, 1, 0, 5, 6, 7, 8, 9]
[3, 2, 0, 1, 4, 5, 6, 7, 8, 9]
[2, 1, 0, 3, 4, 5, 6, 7, 8, 9]
[1, 0, 2, 3, 4, 5, 6, 7, 8, 9]
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
归并排序
把两段有序列表合并成一个有序列表
例如现在有列表li=[2,5,7,8,9,1,3,4,6]
1.这个列表以9为分割线,将列表分为两个部分,左边的部分[2,5,7,8,9]是一个有序列表,右边部分[1,3,4,6]也是一个有序列表
2.分别取这两段有序列表中的第一个元素,分别是2和1,由于1比2小,所以先把1排入一个新列表tmp中
3.再取右边部分的第二个元素3,3比2大,把2排入tmp中1元素的右边
4.再取左边部分的第二个元素5,5比3大,把3排入tmp中2元素右边
5.再取右男家部分的第三个元素4,再对4进行排序
6.直到这两段有序列表中的元素都排入tmp中,这时tmp就是li的有序状态
代码:
def merge(li, left, mid, right):
i = left
j = mid + 1
ltmp = []
while i <= mid and j <= right:
if li[i] <= li[j]:
ltmp.append(li[i])
i += 1
else:
ltmp.append(li[j])
j += 1
while i <= mid:
ltmp.append(li[i])
i += 1
while j <= right:
ltmp.append(li[j])
j += 1
li[left:right + 1] = ltmp
def mergesort(li, left, right):
if left < right:
mid = (left + right) // 2
mergesort(li, left, mid)
mergesort(li, mid + 1, right)
print(li[left:right + 1])
merge(li, left, mid, right)
print(li[left:right + 1])
li = [10, 4, 6, 3, 8, 2, 5, 7, 1, 9]
mergesort(li, 0, len(li) - 1)
print(li)
输出打印:
[10, 4]
[4, 10]
[4, 10, 6]
[4, 6, 10]
[3, 8]
[3, 8]
[4, 6, 10, 3, 8]
[3, 4, 6, 8, 10]
[2, 5]
[2, 5]
[2, 5, 7]
[2, 5, 7]
[1, 9]
[1, 9]
[2, 5, 7, 1, 9]
[1, 2, 5, 7, 9]
[3, 4, 6, 8, 10, 1, 2, 5, 7, 9]
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
归并排序将列表越分越小,直至分成一个元素,
一个元素是有序的
将两个有序列表归并,列表越来越大.
希尔排序
希乐排序是一种分组插入的排序算法
希尔排序每趟并不使某些元素有序,而是使整体数据越来越接近有序
最后一次排序使得所有的数据有序
希尔排序代码:
def shell_sort(li):
gap=len(li) //2
while gap > 0:
for i in range(gap,len(li)):
tmp = li[i]
j = i - gap
while j >=0 and tmp < li[j]:
li[j + gap] = li[j]
j -=gap
li[j + gap] = tmp
print(li)
gap /= 2
li=[10,4,6,3,8,2,5,7,1,9]
shell_sort(li)
print(li)
输出打印:
[2, 4, 6, 3, 8, 10, 5, 7, 1, 9]
[2, 4, 6, 3, 8, 10, 5, 7, 1, 9]
[2, 4, 6, 3, 8, 10, 5, 7, 1, 9]
[2, 4, 6, 1, 8, 10, 5, 7, 3, 9]
[2, 4, 6, 1, 8, 10, 5, 7, 3, 9]
[2, 4, 6, 1, 8, 10, 5, 7, 3, 9]
[2, 1, 6, 4, 8, 10, 5, 7, 3, 9]
[2, 1, 6, 4, 8, 10, 5, 7, 3, 9]
[2, 1, 6, 4, 8, 10, 5, 7, 3, 9]
[2, 1, 5, 4, 6, 10, 8, 7, 3, 9]
[2, 1, 5, 4, 6, 7, 8, 10, 3, 9]
[2, 1, 3, 4, 5, 7, 6, 10, 8, 9]
[2, 1, 3, 4, 5, 7, 6, 9, 8, 10]
[1, 2, 3, 4, 5, 7, 6, 9, 8, 10]
[1, 2, 3, 4, 5, 7, 6, 9, 8, 10]
[1, 2, 3, 4, 5, 7, 6, 9, 8, 10]
[1, 2, 3, 4, 5, 7, 6, 9, 8, 10]
[1, 2, 3, 4, 5, 7, 6, 9, 8, 10]
[1, 2, 3, 4, 5, 6, 7, 9, 8, 10]
[1, 2, 3, 4, 5, 6, 7, 9, 8, 10]
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
排序算法之NB三人组的更多相关文章
- 算法排序-NB三人组
快速排序: 堆排序: 二叉树: 两种特殊二叉树: 二叉树的存储方式: 小结: 堆排序正题: 向下调整: 堆排序过程: 堆排序-内置模块: 扩展问题topk: 归并排序: 怎么使用: NB三人组小结
- 排序NB三人组
排序NB三人组 快速排序,堆排序,归并排序 1.快速排序 方法其实很简单:分别从初始序列“6 1 2 7 9 3 4 5 10 8”两端开始“探测”.先从右往左找一个小于6的数,再从左往 ...
- 列表排序之NB三人组附加一个希尔排序
NB三人组之 快速排序 def partition(li, left, right): tmp = li[left] while left < right: while left < ri ...
- 排序算法Nb三人组-归并排序
归并排序只能对两个已经有序的列表进行合并排序,所以要我们自己创建出两个有序列表.最后在进行合并. def merge2list(li1, li2): li = [] i = 0 j = 0 while ...
- 排序算法Nb三人组-快速排序
核心思想: 将列表中第一个元素拿出来,放到一边,左右两个循环,左面的大于拿出来的数,就把他挪到右面, 右面的小于拿出来的数就把他放在左面,这是列表被第一个元素''分''为两个列表,在对两个列表进行同样 ...
- 算法之LOWB三人组之选择排序
选择排序 思想是在一个列表中每次循环一遍,拿到最小值,接着再从剩下的无序区中继续拿最小值,如此循环,直到结束. 时间复杂度为O(n^2) # 最简单的一个选择排序,循环一个列表,拿到最小值,添加到一个 ...
- 算法NB三人组
#快速排序-除了python自带的sort排序模块之外就这个最好用,只需会这个就行,其他的排序了解就好,能用冒泡,插入..的都可以用快排快速实现 import random from timewrap ...
- 排序算法总结(三)选择排序【Select Sort】
一.原理 选择排序的原理非常简单,就是选出最小(大)的数放在第一位,在剩下的数中,选出最小(大)的数,放在第二位......重复上述步骤,直到最后一个数. 二.过程 原始数据 第一次排序,选出最小的数 ...
- 算法之LOWB三人组之冒泡排序
排序 冒泡排序(Bubble Sort)时间复杂度为O(n^2) 列表每两个相邻的数,如果前面比后面大,则交换这两个数 一趟排序完成后,则无序区减少一个数,有序区增加一个数. def bubble_s ...
随机推荐
- 2017广东工业大学程序设计竞赛初赛 题解&源码(A,水 B,数学 C,二分 D,枚举 E,dp F,思维题 G,字符串处理 H,枚举)
Problem A: An easy problem Description Peter Manson owned a small house in an obscure street. It was ...
- [51nod1299]监狱逃离
到现在还是不会写系列,直接贴题解了. http://www.51nod.com/question/index.html#!questionId=1157 #include<cstdio> ...
- 4395: [Usaco2015 dec]Switching on the Lights
每次到达一个点,或者点亮一个房间的灯的时候,检查一下它四周的点能否走. 一开始看错题了..要求的是最多能开多少房的灯. #include<cstdio> #include<iostr ...
- CodeForces-2015 HIAST Collegiate Programming Contest-Gym-100952A-Who is the winner?
A. Who is the winner? time limit per test 1 second memory limit per test 64 megabytes input standard ...
- BZOJ2425: [HAOI2010]计数
题目:http://www.lydsy.com/JudgeOnline/problem.php?id=2425 其实能够构成的数就是原数的排列(算前导0),然后组合计数一下就可以了. #include ...
- JavaScript八张思维导图—编程风格
JS基本概念 JS操作符 JS基本语句 JS数组用法 Date用法 JS字符串用法 JS编程风格 JS编程实践 不知不觉做前端已经五年多了,无论是从最初的jQuery还是现在火热的Angular,Vu ...
- Spark算子--leftOuterJoin和rightOuterJoin
转载请标明出处http://www.cnblogs.com/haozhengfei/p/cb71cd3ac5d7965a2c61891659264d54.html leftOuterJoin和righ ...
- KEIL MDK 查看代码量、RAM使用情况--RO-data、RW-data、ZI-data
KEIL RVMDK编译后的信息 Code是代码占用的空间, RO-data是 Read Only 只读常量的大小,如const型, RW-data是(Read Write) 初始化了的可读写变量的大 ...
- int指令
body, table{font-family: 微软雅黑; font-size: 13.5pt} table{border-collapse: collapse; border: solid gra ...
- .NET: 谈谈共享项目 (Shared Project) 的使用
从 Visual Studio 2015 起,共享项目 (Shared Project) 作为新的一种项目类型被添加到项目模板列表中,它的主要目的是使多个不同类型的项目之间可以共享代码或资源.相比它的 ...