• 一次请求对多条数据进行排序的算法(一)


    序号order从1开始的递增整数,无间断无重复

    为保证序号不间断、无重复,每次修改数据的序号后,都要对其他的数据序号进行顺移。
    同时移动多条数据是指保证序号不间断、无重复的情况下,一次请求中:之后的数据移动不影响之前移动过的数据的序号。
    移动流程:

    把数据块从位置o移动到位置n,并添加1个锁定块和1个预留位(预留位=n),锁定块不再参与移动
    如果o>n:区域上移
        把m和n(包括m、n)之间的数据(排除锁定块)下移1位
        把预留位的数据下移1位,执行c次(c=预留位数量-1)
    如果o<n:区域下移
        把m和n(包括m、n)之间的数据(排除锁定块)上移1位
        把预留位的数据上移1位,执行c次(c=预留位数量-1)
    重复上面的步骤,直到所有数据被移动到指定的位置

    示意图:

    去重说明:每移动一次会产生一个预留位,下次区域顺移的时候可能会有数据被移动到预留位,这时候需要再次移动预留位上的数据,但是如果有多条相邻的预留位,移动后还是在预留位上,所以最多需要移动c次,c=预留位数量-1。

    下面是一个php实例:

    //要移动的数据
    $rows = array(
        array(
            "id"=>3,/*唯一标识*/
            "moveto"=>8/*目标位置*/
        ),
        array(
            "id"=>4,
            "moveto"=>9
        ),
        array(
            "id"=>12,
            "moveto"=>2
        )
        ...
    )
    $locked = array();//锁定块数组
    $lockedorder = array();//预留位数组
    foreach($rows as $row){
        $o = $db->result("SELECT order FROM ".DB_TABLEPRE."user WHERE  id=$row[$id] ");//数据原来的位置o
        $n = $row[moveto];//目标位置n
        $db->query("update user set order=$n  WHERE  id=".$row[$id]);//移动该条数据
       
        if($n == $o){
            //不用移动
        }elseif($n > $o){
            //区域上移
            $db->query("update user set order=order-1  WHERE  id NOT IN(implode(',',$locked))  AND order>=$o AND order<=$n ");
            //执行c次排重
            foreach($locked as $temp){
                $db->query("update user set order=order-1  WHERE  id NOT IN(implode(',',$locked))  AND order>=$from AND order<=$n  AND order IN(implode(',',$lockedorder))");
            } 
        }else{
            //区域下移
            $db->query("update user set order=order+1  WHERE  id NOT IN(implode(',',$locked))  AND order<=$o AND order>=$n ");
            //执行c次排重
            foreach($locked as $temp){
                $db->query("update user set order=order+1  WHERE  id NOT IN(implode(',',$locked))  AND order<=$o AND order>=$n AND order IN(implode(',',$lockedorder))");
            } 
        }
        $locked [] = $row[$id];//添加一个锁定数据块
        $lockedorder [] = $n;//添加一个预留位
    }
  • 相关阅读:
    Oracle查询当前用户和当前用户下的所有表
    poj 1222EXTENDED LIGHTS OUT
    poj 1753 Flip Game
    老李分享:loadrunner用javavuser进行接口测试
    性能测试培训:帮你定位 Linux 性能问题的 18 个命令以及工具
    cf158B(水题)
    AC自动机讲解+[HDU2222]:Keywords Search(AC自动机)
    [BZOJ2120]:数颜色(分块?)
    赋值运算,拷贝运算,运算符重载
    Fraction to Recurring Decimal(STRING-TYPE CONVERTION)
  • 原文地址:https://www.cnblogs.com/godok/p/6215561.html
Copyright © 2020-2023  润新知