您的位置:首页 > 其它

排序算法,选择,插入,冒泡,归并,希尔排序,树 二叉树算法

2020-02-03 19:24 134 查看

排序算法(英语:Sorting algorithm)是一种能将一串数据依照特定顺序进行排列的一种算法。
冒泡排序
原则
不断的重复‘走访’列表结构,进行相邻元素的比较。
升序: 判断第一个元素是否是比第二个元素大,如果True,则交换
当’走访’ 第一遍的时候,相当于搜索最大元素,并且将最大元素放到最后
list1 = [1, 4, 6, 8, 9, 9, 0, 5, 8, 3, 6, 1, 7]

def bubble_sort(list1):
for i in range(len(list1) - 1, 0, -1): # 11
for j in range(i): # 0 ~ 11
if list1[j] > list1[j + 1]:
list1[j], list1[j + 1] = list1[j + 1], list1[j]

bubble_sort(list1)
print(list1)

选择排序
‘’’
选择排序:

  1. 在未排序的列表中,找出一个最大(小)值,通常找的最大值或者最小值就是列表的第一个元素位置
  2. 然后在未排序的列表中依次找出最大(小)元素位置,
  3. 跟假设的位置进行比较,如果原有位置与找到的最大(小)位置发生改变
  4. 则进行交换

‘’’

list1 = [3, 6, 5, 1, 9]

print('==========>', list1)

def select(list1):
n = len(list1)  # 获取列表的长度

for i in range(n - 1):
min_pos = i  # 假设的最大值的位置

# 从第i+1位置以此类推找max值元素
for j in range(i + 1, n):
if list1[j] < list1[min_pos]:
min_pos = j
# 判断
if min_pos != i:
list1[i], list1[min_pos] = list1[min_pos], list1[i]

print('--------->', list1)

select(list1)
'''
最好,最坏: O(n**2)

'''

冒泡排序:

‘’’
冒泡排序:

‘’’

list1 = [3, 6, 9, 1]

print('====》', list1)

# [1,2,3,4,5]
def bubble(list1):
for i in range(len(list1) - 1, 0, -1):  # i=3  i=2  i=1  ( n-1 )
for j in range(i):  # 3 0  3 1  3 2   (n-1)
if list1[j] > list1[j + 1]:
list1[j], list1[j + 1] = list1[j + 1], list1[j]

print('---->', list1)

bubble(list1)

'''
时间复杂度:
O(n**2)
O(n)

'''

插入排序:

‘’’
插入排序:
插入排序(英语:Insertion Sort)是一种简单直观的排序算法。它的工作原理是通过构建有序序列,
对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入。
插入排序在实现上,在从后向前扫描过程中,需要反复把已排序元素逐步向后挪位,为最新元素提供插入空间。

‘’’

list1 = [3, 6, 5, 1, 9]
print('============>', list1)

def insert(list1):
for i in range(1, len(list1)):
for j in range(i, 0, -1):
if list1[j] < list1[j - 1]:
list1[j], list1[j - 1] = list1[j - 1], list1[j]

print('------>', list1)

insert(list1)

'''
最优: O(n)
最坏: O(n**2)

'''

归并

‘’’
归并排序:
归并排序是采用分治法的一个非常典型的应用。归并排序的思想就是先递归分解数组,再合并数组。

将数组分解最小之后,然后合并两个有序数组,基本思路是比较两个数组的最前面的数,谁小就先取谁,
取了后相应的指针就往后移一位。然后再比较,直至一个数组为空,最后把另一个数组的剩余部分复制过来即可。

‘’’

list1 = [12, 5, 7, 89]

def merge_sort(list1):
if len(list1) <= 1:
return list1
# 二分分解
num = len(list1) // 2

left = merge_sort(list1[:num])  # list1[:2]  12,5  2//2    --->[12]

right = merge_sort(list1[num:])  # --->[5]

print('--->left:', left)
print('--->right:', right)

return merge(left, right)

def merge(left, right):
l, r = 0, 0
result = []
while l < len(left) and r < len(right):
if left[l] < right[r]:
result.append(left[l])
l += 1
else:
result.append(right[r])
r += 1

print('------------------------->', result)

result += left[l:]
result += right[r:]
return result

# 调用
list1 = merge_sort(list1)

print('end:', list1)

归并

‘’’
快速排序(英语:Quicksort),又称划分交换排序(partition-exchange sort),通过一趟排序将要排序的数据分割成独立的两部分,
其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,
以此达到整个数据变成有序序列。

步骤为:
从数列中挑出一个元素,称为"基准"(pivot),
重新排序数列,所有元素比基准值小的摆放在基准前面,所有元素比基准值大的摆在基准的后面(相同的数可以到任一边)。
在这个分区结束之后,该基准就处于数列的中间位置。这个称为分区(partition)操作。
递归地(recursive)把小于基准值元素的子数列和大于基准值元素的子数列排序。
递归的最底部情形,是数列的大小是零或一,也就是永远都已经被排序好了。虽然一直递归下去,
但是这个算法总会结束,因为在每次的迭代(iteration)中,它至少会把一个元素摆到它最后的位置去。
‘’’

list1 = [5, 1, 4, 9, 1, 8, 2, 3, 6]
print('start---->', list1)

def quick(list1, start, end):
if start >= end:
return

# 设定 基准元素
mid = list1[start]

# 从左向右的位置
low = start

# 从右向左走位置
high = end

# 循环
while low < high:
# high不断的向左移动
while low < high and list1[high] >= mid:
high -= 1

# 将high指向的元素放到low位置向
list1[low] = list1[high]

while low < high and list1[low] < mid:
low += 1

list1[high] = list1[low]

# 退出循环后,low与high重合,此时就是基准元素的位置

list1[low] = mid

# 递归  基准元素左边的列表
quick(list1, start, low - 1)

# 递归  基准元素右边的列表
quick(list1, low + 1, end)

quick(list1, 0, len(list1) - 1)

print('---->', list1)

希尔排序

‘’’
希尔排序(Shell Sort)是插入排序的一种。也称缩小增量排序,是直接插入排序算法的一种更高效的改进版本。
希尔排序是非稳定排序算法。该方法因DL.Shell于1959年提出而得名。 希尔排序是把记录按下标的一定增量分组,
对每组使用直接插入排序算法排序;随着增量逐渐减少,每组包含的关键词越来越多,当增量减至1时,整个文件恰被分成一组,算法便终止。

原则:
希尔排序的基本思想是:
将数组列在一个表中并对列分别进行插入排序,重复这过程,不过每次用更长的列(步长更长了,列数更少了)来进行。
最后整个表就只有一列了。将数组转换至表是为了更好地理解这算法,算法本身还是使用数组进行排序。

12,5,7,89,
90,23,56,80,
32,6,8,100 —> [12,5,6,80,32,6,8,89,…]

‘’’

list1 = [12, 5, 7, 89, 90, 23, 56, 80, 43]

print('==========>', list1)

def shell(list1):
n = len(list1)
# 步长
gap = n // 2
print('gap:', gap)
while gap > 0:
# 按照步长进行插入排序
for i in range(gap, n):  # (2,4)  (1,4)
j = i  # j=2
while j >= gap and list1[j - gap] > list1[j]:
list1[j - gap], list1[j] = list1[j], list1[j - gap]
j -= gap

gap = gap // 2
print('---->', list1)

shell(list1)

'''
5,
7,
12,
89

'''

树:

‘’’
tree:
分支
树(英语:tree)是一种抽象数据类型(ADT)或是实作这种抽象数据类型的数据结构,
用来模拟具有树状结构性质的数据集合。它是由n(n>=1)个有限节点组成一个具有层次关系的集合。
把它叫做“树”是因为它看起来像一棵倒挂的树,也就是说它是根朝上,而叶朝下的。它具有以下的特点:

每个节点有零个或多个子节点;
没有父节点的节点称为根节点;
每一个非根节点有且只有一个父节点;
除了根节点外,每个子节点可以分为多个不相交的子树;

二叉树:
完全二叉树:设二叉树的深度为h,除第 h 层外,其它各层 (1~h-1) 的结点数都达到最大个数,
第 h 层所有的结点都连续集中在最左边

满二叉树:深度为k且有2^k-1个结点的二叉树称为满二叉树

常见树形结构:
文件的目录结构
html,xml: DOM操作

</head>

</body>
<div>
<ul>
<li> <a>  <img   /> </a>  </li>
</ul>
</div>
</body>
mysql数据库 ---》 索引

‘’’

class Node:
def __init__(self, data):
self.data = data
self.lchild = None
self.rchild = None

class Tree:
def __init__(self):
self.root = None

def add(self, data):
node = Node(data)
if self.root is None:
self.root = node
return
queue = [self.root]
while queue:
cur = queue.pop(0)
if cur.lchild is None:
cur.lchild = node
return
else:
queue.append(cur.lchild)

if cur.rchild is None:
cur.rchild = node
return
else:
queue.append(cur.rchild)

# 广度优先
def breadth_travel(self):
if self.root is None:
return
queue = [self.root]
while queue:
cur = queue.pop(0)
print(cur.data, sep=' ', end="")
if cur.lchild is not None:
queue.append(cur.lchild)
if cur.rchild is not None:
queue.append(cur.rchild)

# 先序遍历
def front_travel(self, node):
if node is None:
return
print(node.data, end=' ')
self.front_travel(node.lchild)
self.front_travel(node.rchild)

# 中序遍历
def mid_travel(self, node):
if node is None:
return
self.mid_travel(node.lchild)
print(node.data, end=' ')
self.mid_travel(node.rchild)

def rear_travel(self, node):
if node is None:
return
self.rear_travel(node.lchild)
self.rear_travel(node.rchild)
print(node.data, end=' ')

if __name__ == '__main__':
t = Tree()
for i in range(10):
t.add(i)

t.breadth_travel()
print()
# 执行先序遍历
t.front_travel(t.root)
print()
# 中序遍历
t.mid_travel(t.root)
print()
# 后序遍历
t.rear_travel(t.root)
  • 点赞
  • 收藏
  • 分享
  • 文章举报
站内首发文章 xiao_liushui 发布了37 篇原创文章 · 获赞 0 · 访问量 978 私信 关注
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐