排序算法(英语: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操作
<html>
<head>
<title></title>
<script></script>
<style></style>
</head>
</body>
<div>
<ul>
<li> <a> <img /> </a> </li>
</ul>
</div>
</body>
</html>
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)