找回密码
 立即注册

QQ登录

只需一步,快速开始

扫一扫,访问微社区

查看: 1726|回复: 4

[研讨] 堆排序-LISP

[复制链接]

已领礼包: 1757个

财富等级: 堆金积玉

发表于 2014-12-24 08:12:45 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

×
本帖最后由 守仁格竹GM 于 2014-12-24 08:21 编辑

抛砖引玉,对于堆排序尚不清楚,代码属于多C语言直译。希望大家优化。
经测试,目前此函数没有vl-sort运行速度快,慢很多。
  1. ;获取表中第N个元素(从1开始)
  2. ;(setq s (list (list 1 2 3) (list 4 5 6) (list 7 8 9) "123" "555"))
  3. ;(gm-Lst-Nth 2 S) ;获取(4 5 6)
  4. (defun gm-Lst-Nth (N lst)
  5.    (nth (- N 1) lst)
  6. )
  7. ;替换表中第N个元素(从1开始)
  8. ;(gm-Lst-N-Subst "KKK" 2 s)  ;获取:((1 2 3) "KKK" (7 8 9) "123" "555")
  9. (defun gm-Lst-N-Subst (a n lst / i)
  10.   (setq i 0)
  11.   (apply
  12.     'append
  13.     (mapcar
  14.       '(lambda(x)
  15.    (setq i (1+ i))
  16.    (if (= n i)
  17.      (if a (list a) nil)
  18.      (list x)
  19.    )
  20.       )
  21.       lst
  22.     )
  23.   )
  24. )  
  25. (defun gm-HeapAdjust (lst s m / data_s rc j data_j)
  26.   (setq data_s (gm-Lst-Nth s lst))
  27.   (setq rc data_s)
  28.   (setq j (* 2 s))
  29.   (setq data_j (gm-Lst-Nth j lst))
  30.   (while (and (<= rc data_j) (<= j m))
  31.     (if(and (< j m) (< (gm-Lst-Nth j lst) (gm-Lst-Nth (1+ j) lst))) (setq j (1+ j)))
  32.     (if (<= rc (setq data_j (gm-Lst-Nth j lst)))
  33.       (progn
  34.   ;(setq data_s data_j)
  35.   (setq lst (gm-Lst-N-Subst data_j s lst))
  36.   (setq s j)
  37.   (setq j (* j 2))
  38.       )
  39.     )
  40.   )
  41.   (gm-Lst-N-Subst rc s lst)
  42. )

  43. ;(Heap_sort  '(42 13 24 91 23 16 5 88)  8)
  44. (defun Heap_sort (lst long_n / i temp)
  45.   (setq i (fix(* long_n 0.5)))
  46.   (while (> i 0)
  47.     (setq lst (gm-HeapAdjust lst i long_n))
  48.     (setq i (1- i))
  49.   )
  50.   (setq i long_n)
  51.   (while (> i 0)
  52.     (setq temp (nth 0 lst))
  53.     (setq lst (gm-Lst-N-Subst (gm-Lst-Nth i lst) 1 lst))
  54.     (setq lst (gm-Lst-N-Subst temp i lst))
  55.     (setq lst (gm-HeapAdjust lst 1 (1- i)))
  56.     (setq i (1- i))
  57.   )
  58.   lst
  59. )
修改成能够方便应用的排序,代码如下(速度同上--慢):
  1. ;|
  2. (setq lst
  3.        '((42 (1 2 3)) (13 (4 5 6)) (24 (7 8 9))
  4.          (91 (10 11 12)) (23 (13 14 15)) (16 (16 17))
  5.          (5 123) (88 (123))))
  6. (setq   long_n 8)
  7. (pt_Heap_sort lst 8)
  8. |;

  9. (defun pt_Heap_sort (lst long_n / i temp)
  10.   (setq i (fix(* long_n 0.5)))
  11.   (while (> i 0)
  12.     (setq lst (pt_HeapAdjust lst i long_n))
  13.     (setq i (1- i))
  14.   )
  15.   (setq i long_n)
  16.   (while (> i 0)
  17.     (setq temp (nth 0 lst))
  18.     (setq lst (gm-Lst-N-Subst (gm-Lst-Nth i lst) 1 lst))
  19.     (setq lst (gm-Lst-N-Subst temp i lst))
  20.     (setq lst (pt_HeapAdjust lst 1 (1- i)))
  21.     (setq i (1- i))
  22.   )
  23.   lst
  24. )
  25. (defun pt_HeapAdjust (lst s m / data_s rc j data_j)
  26.   (setq data_s (gm-Lst-Nth s lst))
  27.   (setq rc data_s)
  28.   (setq j (* 2 s))
  29.   (setq data_j (gm-Lst-Nth j lst))
  30.   (while (and (<= (car rc) (car data_j)) (<= j m))
  31.     (if(and (< j m) (< (car(gm-Lst-Nth j lst)) (car(gm-Lst-Nth (1+ j) lst)))) (setq j (1+ j)))
  32.     (if (<= (car rc) (car(setq data_j (gm-Lst-Nth j lst))))
  33.       (progn
  34.   ;(setq data_s data_j)
  35.   (setq lst (gm-Lst-N-Subst data_j s lst))
  36.   (setq s j)
  37.   (setq j (* j 2))
  38.       )
  39.     )
  40.   )
  41.   (gm-Lst-N-Subst rc s lst)
  42. )
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!

已领礼包: 1757个

财富等级: 堆金积玉

 楼主| 发表于 2014-12-24 08:23:41 | 显示全部楼层
void HeapAdjust(int data[],int s,int m) /* 排列成堆的形式 */
{
     int j,rc;
     rc=data[s];     /* 保存处理元素 */
     for(j=2*s;j<=m;j*=2)        /* 处理父亲元素 */
     {
          if(j<m && data[j]<data[j+1])  ++j; /* 取较大的孩子节点 */
          if(rc>data[j]) break;
          data[s]=data[j];   /* 父节点比较大的孩子节点大则互换 ,保证父节点比所有子节点都大(父节点存储在前面)*/
          s=j;
     }
    data[s]=rc;     /* 相当于data[j]=rc */
}
void Heap_sort(int data[],int long_n) /* 堆排序函数 */
{
     int i,temp;
     for(i=long_n/2;i>0;--i)  /* 还没有读懂这样处理的原因,希望大家不吝赐教 */
     {
      HeapAdjust(data,i,long_n); /* 处理后,data[i]是这个数组后半部分的最大值 */
     }
     for(i=long_n;i>0;--i)
     {
      temp=data[1];    /* 把根元素(剩下元素中最大的那个)放到结尾 ,下一次只要排剩下的数就可以啦*/
      data[1]=data[i];
      data[i]=temp;   
      HeapAdjust(data,1,i-1);
     }
}
这是对应的C语言代码
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

已领礼包: 604个

财富等级: 财运亨通

发表于 2014-12-24 08:34:09 | 显示全部楼层
高飞的
http://bbs.xdcad.net/forum.php?m ... peid%26typeid%3D123
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

已领礼包: 19个

财富等级: 恭喜发财

发表于 2014-12-24 09:47:32 | 显示全部楼层
可以像VL-SORT那样,支持带任意的子表排序吗?
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

已领礼包: 1903个

财富等级: 堆金积玉

发表于 2014-12-27 15:07:48 来自手机 | 显示全部楼层
想了个效率很低的整数排序算法,1,根据表lst中的最小,最大值构造一个逐步增1的有序表lst0;2,对表lst0中每个元素e做判断,若e为lst中的某一元素,则输出该元素,得到排序后的结果。
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|申请友链|Archiver|手机版|小黑屋|辽公网安备|晓东CAD家园 ( 辽ICP备15016793号 )

GMT+8, 2025-9-20 07:41 , Processed in 0.443365 second(s), 43 queries , Gzip On.

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

快速回复 返回顶部 返回列表