当前位置: 首页 > article >正文

算法---找出一组序列中的第k小(大)的元素

#第一种:分组比较
def partition(seq):
    pi = seq[0]
    lo = []
    hi = []
    for element in seq[1:]:
        if element <= pi:
            lo.append(element)
        else:
            hi.append(element)
    return lo, pi, hi


def select(seq, k):
    if not seq:  # 检查输入序列是否为空
        raise ValueError("输入的序列不能为空")
    if k < 0 or k >= len(seq):  # 检查k值是否合法
        raise ValueError("k值超出了序列长度范围")
    lo, pi, hi = partition(seq)
    m = len(lo)
    if m == k:
        return pi
    elif m < k:
        return select(hi, k - m - 1)
    else:
        return select(lo, k)


if __name__ == '__main__':
    seq = [3, 4, 1, 6, 3, 7, 9, 13, 93, 0, 100, 1, 2, 2, 3, 3, 2]
    try:
        print(select(seq, 3))
        print(select(seq, 1))
    except ValueError as e:
        print(e)
# 第二种:快速排序的分治算法
def quicksort(num, low, high):
    if low < high:
        location = partition(num, low, high)
        quicksort(num, low, location - 1)
        quicksort(num, location + 1, high)

def partition(num, low, high):
    pivot = num[high]  # 基准值选择最后一个元素
    while low < high:
        while low < high and num[low] <= pivot:  # 寻找比基准值大的元素
            low += 1
        while low < high and num[high] >= pivot:  # 寻找比基准值小的元素
            high -= 1
        if low < high:
            temp = num[low]
            num[low] = num[high]
            num[high] = temp
    num[high] = pivot  # 将基准值放到中间
    return high

def findkth(num, low, high, k):
    index = partition(num, low, high)
    if index == k:
        return num[index]
    elif index < k:
        return findkth(num, index + 1, high, k)
    else:
        return findkth(num, low, index - 1, k)

pai = [2, 3, 1, 5, 4, 6]
quicksort(pai, 0, len(pai) - 1)  # 先对数组进行排序
print(findkth(pai, 0, len(pai) - 1, 5))  # 打印第5小的元素

#第三种:分组和排序同时进行
def selectTopK(a, low, high, k):
    if low == high and k == 0:
        return a[0]
    pivotkey = a[high]
    i, j = low, high
    while i < j:
        while i < j and a[i] <= pivotkey:  # 比较操作符
            i += 1
        a[i], a[j] = a[j], a[i]  # 先交换元素
        while i < j and a[j] >= pivotkey:  # 比较操作符
            j -= 1
        a[i], a[j] = a[j], a[i]  # 再交换元素
    print('i:', i)
    if k < i:
        return selectTopK(a, low, i - 1, k)
    elif k > i:
        return selectTopK(a, i + 1, high, k)
    else:
        return a[i]

# 测试函数
print(selectTopK([1, 5, 3, 4, 2, 3], 0, 5, 3))
#第四种:生成随机校验码
import random
def selectTopK(a, low, high, k):
    if low == high and k == 1:
        return a[low]
    m = random.randint(low, high)
    pivotkey = a[m]
    a[m], a[high] = a[high], a[m]
    i = low - 1
    for j in range(low, high):
        if a[j] < pivotkey:
            i += 1
            a[i], a[j] = a[j], a[i]
    a[i + 1], a[high] = a[high], a[i + 1]
    print('i:', i + 1)
    t = i + 1
    if k < t:
        return selectTopK(a, low, i, k)
    elif k > t:
        return selectTopK(a, i + 2, high, k - t)
    else:
        return a[i + 1]

# 测试代码
print(sorted([1, 5, 3, 4, 2, 3, 9]))
print(selectTopK([1, 5, 3, 4, 2, 3, 9], 0, 6, 1))

输出结果:

第二种:

第三种:
 

 

第四种:

 


http://www.kler.cn/a/397451.html

相关文章:

  • C++创建型设计模式体现出的面向对象设计原则
  • Java爬虫(HttpURLConnection)详解
  • 无人机检测车辆——多目标检测
  • CentOS8 在MySQL8.0 实现半同步复制
  • java项目-jenkins任务的创建和执行
  • FRP 实现内网穿透
  • 每日算法一练:剑指offer——栈与队列篇(1)
  • OTX 架构开发需求分析
  • JAVA_单例模式
  • 安全生产管理的重要性:现状、痛点与改进之路
  • Android 12.0 第三方app授予DeviceOwner权限调用系统reboot,显示隐藏app,锁屏,禁用app等功能系统层部分实现
  • Java中的HTML元素设置:背景、列表与超链接
  • Docker占用空间太大磁盘空间不足清理妙招
  • 深度学习在边缘检测中的应用及代码分析
  • 保存数据到Oracle时报错ORA-17004: 列类型无效: 1111
  • 【第四期书生大模型实战营基础岛】L1G4000——LlamaIndex+InternLM RAG 实践
  • C语言模块化概述
  • LeetCode100之环形链表(141)--Java
  • HashMap源码分析上-红黑树
  • 「Mac玩转仓颉内测版7」入门篇7 - Cangjie控制结构(下)
  • [系统安全] PE文件知识在免杀中的应用
  • Spring:DI依赖注入的方式
  • Kafka 到 Kafka 数据同步
  • 牛客挑战赛77
  • PHP反序列化靶场(php-SER-libs-main 第一部分)
  • Servlet⾥面的doPost-doGet和路路径匹配讲解(笔记)