Python学习-day13 排序方法

冒泡排序

冒泡排序(Bubble Sort)也是一种简单直观的排序算法。它重复地走访过要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来。

def bubbleSort(arr):
    n = len(arr)
    for i in range(n):
        for j in range(0, n - i - 1):
            if arr[j] > arr[j + 1]:
                arr[j], arr[j + 1] = arr[j + 1], arr[j]
    return arr
                
arr = [64, 34, 25, 12, 22, 11, 90]
print(f"排序前:{arr}")
tmp = bubbleSort(arr)
print(f"排序后:{tmp}")

排序前:[64, 34, 25, 12, 22, 11, 90]
排序后:[11, 12, 22, 25, 34, 64, 90]

插入排序

插入排序(英语:Insertion Sort)是一种简单直观的排序算法。它的工作原理是通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入。

def insertionSort(arr): 
    n = len(arr)
    for i in range(1, n): 
        key = arr[i] 
  
        j = i - 1
        while j >=0 and key < arr[j]: 
                arr[j + 1] = arr[j] 
                j -= 1
        arr[j + 1] = key 
    
    return arr
                
arr = [64, 34, 25, 12, 22, 11, 90]
print(f"排序前:{arr}")
tmp = insertionSort(arr)
print(f"排序后:{tmp}")

排序前:[64, 34, 25, 12, 22, 11, 90]
排序后:[11, 12, 22, 25, 34, 64, 90]

快速排序

快速排序使用分治法(Divide and conquer)策略来把一个序列(list)分为较小和较大的2个子序列,然后递归地排序两个子序列。

def partition(arr, low, high): 
    i = (low - 1) # 最小元素索引
    pivot = arr[high]     
  
    for j in range(low , high): 
        # 当前元素小于或等于 pivot 
        if arr[j] <= pivot: 
            i = i + 1 
            arr[i], arr[j] = arr[j], arr[i] 
    arr[i + 1], arr[high] = arr[high], arr[i + 1] 
    return (i + 1) 
  
# 快速排序函数
def quickSort(arr, low, high): 
    if low < high: 
        pi = partition(arr,low,high) 
        quickSort(arr, low, pi - 1) 
        quickSort(arr, pi + 1, high) 
        
    return arr
        
                
arr = [64, 34, 25, 12, 22, 11, 90]
print(f"排序前:{arr}")
tmp = quickSort(arr, 0, len(arr) - 1)
print(f"排序后:{tmp}")

排序前:[64, 34, 25, 12, 22, 11, 90]
排序后:[11, 12, 22, 25, 34, 64, 90]

选择排序

选择排序(Selection sort)是一种简单直观的排序算法。它的工作原理如下。首先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置,然后,再从剩余未排序元素中继续寻找最小(大)元素,然后放到已排序序列的末尾。以此类推,直到所有元素均排序完毕。

def selectionSort(arr):
    n = len(arr)
    for i in range(n):
        min_idx = i 
        for j in range(i + 1, n): 
            if arr[min_idx] > arr[j]: 
                min_idx = j 
                
        arr[i], arr[min_idx] = arr[min_idx], arr[i] 
    return arr
                
arr = [64, 34, 25, 12, 22, 11, 90]
print(f"排序前:{arr}")
tmp = selectionSort(arr)
print(f"排序后:{tmp}")

排序前:[64, 34, 25, 12, 22, 11, 90]
排序后:[11, 12, 22, 25, 34, 64, 90]

归并排序

归并排序(英语:Merge sort,或mergesort),是创建在归并操作上的一种有效的排序算法。

def merge(arr, l, m, r): 
    n1 = m - l + 1
    n2 = r- m 
  
    # 创建临时数组
    L = [0] * (n1)
    R = [0] * (n2)
  
    # 拷贝数据到临时数组 arrays L[] 和 R[] 
    for i in range(0 , n1): 
        L[i] = arr[l + i] 
  
    for j in range(0 , n2): 
        R[j] = arr[m + 1 + j] 
  
    # 归并临时数组到 arr[l..r] 
    i = 0 # 初始化第一个子数组的索引
    j = 0 # 初始化第二个子数组的索引
    k = l # 初始归并子数组的索引
  
    while i < n1 and j < n2: 
        if L[i] <= R[j]: 
            arr[k] = L[i] 
            i += 1
        else: 
            arr[k] = R[j] 
            j += 1
        k += 1
  
    # 拷贝 L[] 的保留元素
    while i < n1: 
        arr[k] = L[i] 
        i += 1
        k += 1
  
    # 拷贝 R[] 的保留元素
    while j < n2: 
        arr[k] = R[j] 
        j += 1
        k += 1
  
def mergeSort(arr,l,r): 
    if l < r: 
        m = int((l+(r-1))/2)
       
        mergeSort(arr, l, m) 
        mergeSort(arr, m + 1, r) 
        merge(arr, l, m, r) 
    return arr    
                
arr = [64, 34, 25, 12, 22, 11, 90]
print(f"排序前:{arr}")
tmp = mergeSort(arr, 0, len(arr) - 1)
print(f"排序后:{tmp}")

排序前:[64, 34, 25, 12, 22, 11, 90]
排序后:[11, 12, 22, 25, 34, 64, 90]

堆排序

堆排序(Heapsort)是指利用堆这种数据结构所设计的一种排序算法。堆积是一个近似完全二叉树的结构,并同时满足堆积的性质:即子结点的键值或索引总是小于(或者大于)它的父节点。堆排序可以说是一种利用堆的概念来排序的选择排序。

def heapify(arr, n, i): 
    largest = i  
    l = 2 * i + 1 # left = 2*i + 1 
    r = 2 * i + 2 # right = 2*i + 2 
  
    if l < n and arr[i] < arr[l]: 
        largest = l 
  
    if r < n and arr[largest] < arr[r]: 
        largest = r 
  
    if largest != i: 
        arr[i],arr[largest] = arr[largest],arr[i]  # 交换
  
        heapify(arr, n, largest) 
  
def heapSort(arr): 
    n = len(arr) 
  
    # Build a maxheap. 
    for i in range(n, -1, -1): 
        heapify(arr, n, i) 
  
    # 一个个交换元素
    for i in range(n-1, 0, -1): 
        arr[i], arr[0] = arr[0], arr[i] # 交换
        heapify(arr, i, 0) 
    
    return arr
  
                
arr = [64, 34, 25, 12, 22, 11, 90]
print(f"排序前:{arr}")
tmp = heapSort(arr)
print(f"排序后:{tmp}")

排序前:[64, 34, 25, 12, 22, 11, 90]
排序后:[11, 12, 22, 25, 34, 64, 90]

计数排序

计数排序的核心在于将输入的数据值转化为键存储在额外开辟的数组空间中。作为一种线性时间复杂度的排序,计数排序要求输入的数据必须是有确定范围的整数

def countSort(arr): 
    output = [0 for i in range(256)] 
    count = [0 for i in range(256)] 
    ans = ["" for _ in arr] 
  
    for i in arr: 
        count[ord(i)] += 1
  
    for i in range(256): 
        count[i] += count[i-1] 
  
    for i in range(len(arr)): 
        output[count[ord(arr[i])]-1] = arr[i] 
        count[ord(arr[i])] -= 1
  
    for i in range(len(arr)): 
        ans[i] = output[i] 
    return ans  
  
                
arr = "helloPython"
print(f"排序前:{arr}")
tmp = countSort(arr)
print(f"排序后:{tmp}")

排序前:helloPython
排序后:[‘P’, ‘e’, ‘h’, ‘h’, ‘l’, ‘l’, ‘n’, ‘o’, ‘o’, ‘t’, ‘y’]

希尔排序

希尔排序,也称递减增量排序算法,是插入排序的一种更高效的改进版本。但希尔排序是非稳定排序算法。
希尔排序的基本思想是:先将整个待排序的记录序列分割成为若干子序列分别进行直接插入排序,待整个序列中的记录"基本有序"时,再对全体记录进行依次直接插入排序。

def shellSort(arr): 
    n = len(arr)
    gap = int(n / 2)
  
    while gap > 0: 
        for i in range(gap,n): 
            temp = arr[i] 
            j = i 
            while  j >= gap and arr[j-gap] >temp: 
                arr[j] = arr[j-gap] 
                j -= gap 
            arr[j] = temp 
        gap = int(gap / 2)
    return arr

                
arr = [64, 34, 25, 12, 22, 11, 90]
print(f"排序前:{arr}")
tmp = shellSort(arr)
print(f"排序后:{tmp}")

排序前:[64, 34, 25, 12, 22, 11, 90]
排序后:[11, 12, 22, 25, 34, 64, 90]

拓扑排序

对一个有向无环图(Directed Acyclic Graph简称DAG)G进行拓扑排序,是将G中所有顶点排成一个线性序列,使得图中任意一对顶点u和v,若边(u,v)∈E(G),则u在线性序列中出现在v之前。通常,这样的线性序列称为满足拓扑次序(Topological Order)的序列,简称拓扑序列。简单的说,由某个集合上的一个偏序得到该集合上的一个全序,这个操作称之为拓扑排序。

from collections import defaultdict 
 
class Graph: 
    def __init__(self, vertices): 
        self.graph = defaultdict(list) 
        self.V = vertices
  
    def addEdge(self, u, v): 
        self.graph[u].append(v) 
  
    def topologicalSortUtil(self, v, visited, stack): 
        visited[v] = True
  
        for i in self.graph[v]: 
            if visited[i] == False: 
                self.topologicalSortUtil(i, visited, stack) 
  
        stack.insert(0, v) 
  
    def topologicalSort(self): 
        visited = [False] * self.V 
        stack = [] 
  
        for i in range(self.V): 
            if visited[i] == False: 
                self.topologicalSortUtil(i,visited,stack) 
  
        print(stack) 
  
g = Graph(6) 
g.addEdge(5, 2); 
g.addEdge(5, 0); 
g.addEdge(4, 0); 
g.addEdge(4, 1); 
g.addEdge(2, 3); 
g.addEdge(3, 1); 
  
print ("拓扑排序结果:")
g.topologicalSort()

拓扑排序结果:
[5, 4, 2, 3, 1, 0]

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值