我的编程空间,编程开发者的网络收藏夹
学习永远不晚

快排实现仿order by多字段排序

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

快排实现仿order by多字段排序

class OrderBy(object):

    def __init__(self, sequence, *condition, **extra_condition):
        """
        排序初始化条件
        condition为优先排序条件,序列内元素必须为字典类型
        extra_condition为额外的条件因素,当condition不存在时,额外条件才会生效
        :param sequence:
        :param condition:
        :param extra_condition:
        """
        self.array = sequence
        self.condition = list(condition)
        self.extra_condition = extra_condition
        self.has_condition = bool(self.condition)

    def partition(self, left, right, key=None, desc=False, func=None):
        """
        将区间数据进行排序
        分区比较,选择一个基准,根据排序规则,正序:比基准大的放右边,比基准小的放左边
        :param left: 序列区间的开始位置
        :param right: 序列区间的结束位置
        :param key: 对于字典对象,如果指定key,则以key对象比较否则当None值处理
        :param desc: 比较规则为正序或倒序
        :param func: 对值进行处理特殊处理的函数
        :return:
        """
        pivot = self.array[left]
        if isinstance(pivot, dict):
            if key is not None:
                pivot = pivot.get(key)
        if callable(func):
            pivot = func(pivot)
        low = left
        while low < right:
            while low < right:
                _left = self.array[low]
                _right = self.array[right]
                if isinstance(_left, dict):
                    _left = _left.get(key)
                if isinstance(_right, dict):
                    _right = _right.get(key)
                if callable(func):
                    _left = func(_left)
                    _right = func(_right)
                if desc:
                    # 倒序,右边值与基准值都不为空,且右边值小于基准值,左移
                    if _right and pivot and _right < pivot:
                        right -= 1
                    # 倒序,右边值为空,左移
                    elif not _right:
                        right -= 1
                    # 倒序,左边值与基准值都不为空,且左边值大于等于基准值,右移
                    elif _left and pivot and _left >= pivot:
                        low += 1
                    # 倒序,基准值为空,左边值不为空,右移
                    elif _left and not pivot:
                        low += 1
                    else:
                        break
                else:
                    # 正序,基准为空,右边值不为空,左移
                    if _right and not pivot:
                        right -= 1
                    # 正序,右边值与基准都不为空,且右边值大于基准值,左移
                    elif _right and pivot and _right > pivot:
                        right -= 1
                    # 正序,左边值与基准都不为空,且左边值小于等于基准值,右移
                    elif _left and pivot and _left <= pivot:
                        low += 1
                    # 正序,左边值为空,右移
                    elif not _left:
                        low += 1
                    else:
                        break
            if low < right:
                temp = self.array[low]
                self.array[low] = self.array[right]
                self.array[right] = temp
        self.array[left], self.array[low] = self.array[low], self.array[left]
        return low

    def quick_sort(self, left=0, right=None, key=None, desc=False, func=None):
        """
        快速排序算法
        :param left: 区间起始位置
        :param right: 区间结束位置
        :param key: 字典元素使用指定键名值排序
        :param desc: 是否倒序
        :param func: 对于排序值,支持使用函数处理
        :return:
        """
        if right is None:
            right = len(self.array) - 1
        if left < right:
            pivot_position = self.partition(left, right, key, desc, func)
            self.quick_sort(left, pivot_position - 1, key, desc, func)
            self.quick_sort(pivot_position + 1, right, key, desc, func)

    def sort(self, **condition):
        if self.has_condition:
            if not self.condition:
                return
            _condition = self.condition.pop(0)
            if isinstance(_condition, dict):
                condition['key'] = _condition.get('key')
                condition['desc'] = _condition.get('desc', False)
        else:
            condition.update(**self.extra_condition)
        left = condition.get('left')
        right = condition.get('right')
        if not left:
            left = 0
            condition['left'] = left
        if not right:
            right = len(self.array) - 1
            condition['right'] = right
        self.quick_sort(**condition)
        self.sub_sort(left, right, condition.get('key'))

    def sub_sort(self, left, right, key=None, next_index=0):
        """
        标记当前位置begin,及下一个位置end
        当begin位置的元素与end位置元素不等时,当begin!=end - 1时,则进行区间排序
        :param left: 区间起始位置
        :param right: 区间结束位置
        :param key: 当前排序键名
        :param next_index: 下一个条件位置
        :return:
        """
        condition_size = len(self.condition)
        if not condition_size > next_index:
            return
        begin = left
        for end in range(left, right + 1):
            _left = self.array[begin]
            _right = self.array[end]
            if isinstance(_left, dict):
                _left = _left.get(key)
            if isinstance(_right, dict):
                _right = _right.get(key)
            # 当上一个值与当前值不相等,则进入二次排序
            # 当上一个值与当前值相等,且当前位置等于边界位置,且还有下一个排序条件,则进入二次排序
            if _left != _right or (
                    end == right and condition_size >= next_index + 1):
                condition = self.condition[next_index]
                _key = condition.get('key')
                desc = condition.get('desc')
                func = condition.get('func')
                if end == right:
                    _end = end
                else:
                    _end = end - 1
                self.quick_sort(begin, _end, _key, desc, func)
                self.sub_sort(begin, end, _key, next_index + 1)
                begin = end


if __name__ == '__main__':
    a = [dict(age=18, money=200, name='z1'),
         dict(age=16, money=200, name='z2'),
         dict(age=16, money=200, name='z3'),
         dict(age=16, money=100, name='z4'),
         dict(age=16, money=200, name='z5')]
    order_by = OrderBy(a, dict(key='age', desc=False),
                       dict(key='money', desc=True),
                       dict(key='name', desc=True))
    print(a)
    order_by.sort()
    print(a)

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

快排实现仿order by多字段排序

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

快排实现仿order by多字段排序

class OrderBy(object): def __init__(self, sequence, *condition, **extra_condition): """ 排序初始化条件
2023-01-30

详解MySQL中Order By排序和filesort排序的原理及实现

目录1.Order By原理2.filesort排序算法3.优化排序1.Order By原理mysql的Order By操作用于排序,并且会有多种不同的排序算法,他们的性能都是不一样的。假设有一个表,建表的sql如下:CREATE T
2022-08-16

Java字符串字段升序排序怎么实现

你可以使用Java中的`Arrays.sort()`方法来实现字符串字段的升序排序。以下是一个示例代码:```javaimport java.util.Arrays;public class StringSortExample {publi
2023-09-14

sql怎么实现两个字段排序

在SQL中,可以使用ORDER BY子句对查询结果进行排序。可以指定多个字段进行排序,例如:```sqlSELECT * FROM 表名ORDER BY 字段1, 字段2;```以上语句将根据字段1进行升序排序,并在字段1相同时,根据字段2
2023-09-14

mysql实现将字符串字段转为数字排序或比大小

目录将字符串字段转为数字排序或比大小排序比大小sql语句字符串如何比较大小解决方法将字符串字段转为数字排序或比大小mysql里面有个坑就是,有时按照某个字段的大小排序(或是比http://www.cppcns.com大小)发现排序有点错乱
2022-06-13

php二维数组根据某个字段排序怎么实现

可以使用usort()函数来实现二维数组根据某个字段排序。下面是一个示例代码:$students = array(array('name' => 'Alice', 'score' => 80),array('name' => 'Bob'
2023-10-27

oracle实现根据字段分组排序,取其第一条数据

这篇文章主要介绍了oracle实现根据字段分组排序,取其第一条数据方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
2023-02-28

Golang多线程排序实现快速高效地处理大规模数据

Golang多线程排序是一种快速高效地处理大规模数据的方法,通过使用Golang的协程和通道,可以将排序任务分配到多个线程中并行处理,提高了排序的效率和速度,需要详细了解可以参考下文
2023-05-19

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录