马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?立即注册
×
- ;;; File : lispsort.lsp
- ;;; Purpose : Samples of power sorting in AutoLisp
- ;;;
- ;;; Author : T.J. DiTullio Herman Goldner Co. Inc.
- ;;; (70214,3131)
- ;;;
- ;;; Date : 3-23-95 (complied from earlier files 1992)
- ;;;
- ;;; Desciption : Here are four sorting functions that implement
- ;;; sorting with pointers (Yes in AutoLisp).
- ;;; There are two shell sorts and two bubble sorts
- ;;; One of each for lists and one for list of lists
- ;;;
- ;;; After I developed these functions, I speed tested
- ;;; the shells against the bubbles. Since then I have not
- ;;; used the bubble sorts.
- ;;;
- ;;; All four functions use an integer list (ptr_lst) as
- ;;; pointers to the list to be sorted. One problem with
- ;;; sorting in AutoLisp is that the list to be sorted must
- ;;; be reconstructed each time a pair of items are swapped
- ;;; If the list (or list of lists) is very large, it can
- ;;; slow down the sort. By using a pointer list of type
- ;;; integer, this reconstruction will be much faster.
- ;;;
- ;;; At the start of each sort function, an integer list
- ;;; (ptr_lst) is constructed starting at 0 and ending at
- ;;; the number of items in list to be sorted (length lst).
- ;;; As items in the list to be sorted are compared, the
- ;;; pointer list is used to reference the list to be sorted.
- ;;; [ something like (nth (nth index ptr_lst) lst) ]
- ;;; [ meaning - The value of the list to be sorted is still
- ;;; in its original location. Used the integer
- ;;; (ptr_lst) value to determine where it is.
- ;;; ]
- ;;; Since the pointer list starts at 0, I used value of -1
- ;;; for the 1st (subst) call to avoid have duplicate values in
- ;;; the pointer list that would both be updated on the 2nd
- ;;; (subst) call. Then after the 2nd (subst) call, a 3rd call
- ;;; is made to replace the -1 value with the correct value.
- ;;; (setq t1 1st_item) - save 1st
- ;;; (setq t2 2nd_item) - save 2nd
- ;;; (subst -1 t1) - change t1 to -1
- ;;; (subst t1 t2) - change t2 to t1
- ;;; (subst t2 -1) - change -1 to t2
- ;;; - t1 and t2 are >= 0 always
- ;;;
- ;;; As items are swapped around, only the pointer list is
- ;;; modified. After the sorting is completed, the list to
- ;;; be sorted to rebuilt using the pointer list for the
- ;;; sorted location.
- ;;;
- ;;; This may seem like a lot of work to do some sorting. But
- ;;; the list of list that I sort get very large. (I use list
- ;;; of lists like an array of structures for anyone who knows
- ;;; the C language)
- ;;;
- ;;; Here is an example for a list of lists I might sort:
- ;;; ( ( "string" integer real integer real real "string"
- ;;; "string" real integer "string" real
- ;;; )
- ;;; ( "string" integer real integer real real "string"
- ;;; "string" real integer "string" real
- ;;; )
- ;;; etc ...
- ;;; )
- ;;;
- ;;; lisp call -> (setq mylist (l_ssort mylist 3))
- ;;; lisp retn -> sorted list
- ;;; description -> sort mylist bases on the 4th item (an integer)
- ;;;
- ;;;
- ;;; One thing I noticed when I wrote these sorts was that
- ;;; a shell sort is unable to sort completely if there are
- ;;; duplicate values. I could not find anything in writing
- ;;; to back this up. So I modified the algorithm to continue
- ;;; looping while the partition size is one until no swaps
- ;;; occurred.
- ;;;
- ;;; Sorry there are not a lot of comments!
- ;;;
- ;;; If you program in AutoLisp and are unfamiliar with these
- ;;; sorting methods, try looking at another language like
- ;;; Basic or C.
- ;;;
- ;;; Any comments or questions can be directed to me.
- ;;;
- ;;;
- ;;; THIS CODE IS THE PROPERTY OF T.J. DITULLIO AND THE HERMAN GOLDNER CO INC
- ;;; PERMISSION IS GRANTED TO USE, COPY, MODIFY, AND DISTRIBUTE WITHOUT FEE
- ;;; PROVIDED THAT THIS NOTICE IS DISTRIBUTED.
- ;;;
- ;;;* * * * * * * * * * * * * SORT FUNCTIONS * * * * * * * * * * * * * * *
- ;;;
- ;;; l_bsort
- ;;;
- ;;; Modified Bubble Sort of List of Lists
- ;;; Parameters llist -> list of lists
- ;;; key -> element in inner lists to sort by
- ;;;
- ;;; Returns -> Sorted list of lists
- ;;;
- (defun l_bsort ( llist key / number_items count i
- unsorted ptr_lst j
- sorted_list t1 t2
- )
- (if (and llist key)
- (progn
- (setq i 1
- number_items (length llist)
- unsorted T
- ptr_lst nil ;pointer list
- count 0
- )
- (while (< count number_items)
- (setq ptr_lst (append ptr_lst (list count)) ;built pointer list
- count (1+ count)
- )
- ) ;while
- ;-----------------------------------------------------------------------
- (while (or unsorted (< i number_items))
- (setq j 0
- unsorted nil ;assume list is sorted
- )
- ;loop thru and test (j) to (J+1) in pointer list
- (while (< j (- number_items i))
- (if (> (nth key (nth (nth j ptr_lst) llist))
- (nth key (nth
- (nth (1+ j) ptr_lst) llist)
- )
- )
- ; swap items in pointer list
- (setq t1 (nth j ptr_lst)
- t2 (nth (1+ j) ptr_lst)
- ptr_lst (subst t2 -1
- (subst t1 t2
- (subst -1 t1 ptr_lst)
- )
- )
- unsorted T
- ) ;setq
- ) ;if
- (setq j (1+ j))
- ) ;while j
- (setq i (1+ i))
- ) ;while i
- ;-----------------------------------------------------------------------
- ;Build new list using sorted pointers
- (setq count 0 sorted_list nil)
- (while (< count number_items)
- (setq sorted_list
- (append sorted_list ;build updated list
- (list
- (nth
- (nth count ptr_lst) ;pointer
- llist
- )
- )
- )
- count (1+ count)
- ) ;setq
- ) ;while
- sorted_list ;return sorted list
- ) ;progn
- ;else
- nil
- ) ;if
- ) ;defun
- ;;;=======================================================================
- ;;;
- ;;; l_ssort
- ;;;
- ;;; Modified Shell Sort of List of Lists
- ;;; Parameters llist -> list of lists
- ;;; key -> element in inner lists to sort by
- ;;;
- ;;; Returns -> Sorted list of lists
- ;;;
- ;;; Note: This custom shell sort algorithm will handle multiple
- ;;; occurrences of any items. The sort will continue looping
- ;;; when partition size is 1 until no swaps occur.
- ;;;
- (defun l_ssort (llist key /
- number_items partition_size
- number_partitions first_index
- last_index unsorted
- count ptr_lst
- sorted_list i j
- t1 t2
- )
- (if (and llist key)
- (progn
- (setq number_items (length llist)
- partition_size number_items
- ptr_lst nil ;pointer list
- count 0
- unsorted T ;assume list is not sorted
- )
- (while (< count number_items)
- (setq ptr_lst (append ptr_lst (list count)) ;built pointer list
- count (1+ count)
- )
- ) ;while
- ;------------------------------------------------------------------
- (while unsorted
- (setq partition_size (fix (/ (1+ partition_size) 2))
- number_partitions (fix (/ number_items partition_size))
- )
- (if (= partition_size 1)
- (setq unsorted nil) ;assume list is sorted
- )
- (if (/= (rem number_items partition_size) 0)
- (setq number_partitions (1+ number_partitions))
- )
- (setq first_index 0
- i 1
- )
- (while (< i number_partitions)
- (setq last_index (+ first_index partition_size))
- (if (> last_index (- number_items partition_size))
- (setq last_index (- number_items partition_size))
- )
- ;loop thru and test (j) to (j+offset) in pointer list
- (setq j first_index)
- (while (< j last_index)
- (if (> (nth key (nth (nth j ptr_lst) llist))
- (nth key (nth
- (nth (+ j partition_size) ptr_lst) llist)
- )
- )
- ; then swap items in pointer list
- (setq t1 (nth j ptr_lst)
- t2 (nth (+ j partition_size) ptr_lst)
- ptr_lst (subst t2 -1
- (subst t1 t2
- (subst -1 t1 ptr_lst)
- )
- )
- unsorted T
- ) ;setq
- ) ;if
- (setq j (1+ j))
- ) ;while j
- (setq first_index (+ first_index partition_size)
- i (1+ i)
- )
- ) ;while i
- ) ;while unsorted
- ;------------------------------------------------------------------
- ;Build new list using sorted pointers
- (setq count 0 sorted_list nil)
- (while (< count number_items)
- (setq sorted_list
- (append sorted_list ;build updated list
- (list
- (nth
- (nth count ptr_lst) ;pointer
- llist
- )
- )
- )
- count (1+ count)
- ) ;setq
- ) ;while
- sorted_list ;return sorted list
- ) ;progn
- ;else
- nil
- ) ;if
- ) ;defun
- ;;;=======================================================================
- ;;;
- ;;; bsort
- ;;;
- ;;; Modified Bubble Sort of List of values
- ;;; Parameters lst -> list of values
- ;;;
- ;;; Returns -> Sorted list of values
- ;;;
- (defun bsort ( lst / number_items count i
- unsorted ptr_lst j
- sorted_list t1 t2
- )
- (if lst
- (progn
- (setq i 1
- number_items (length lst)
- unsorted T
- ptr_lst nil ;pointer list
- count 0
- )
- (while (< count number_items)
- (setq ptr_lst (append ptr_lst (list count)) ;built pointer list
- count (1+ count)
- )
- ) ;while
- ;-----------------------------------------------------------------------
- (while (or unsorted (< i number_items))
- (setq j 0
- unsorted nil ;assume list is sorted
- )
- ;loop thru and test (j) to (J+1) in pointer list
- (while (< j (- number_items i))
- (if (> (nth (nth j ptr_lst) lst)
- (nth (nth (1+ j) ptr_lst) lst)
- )
- ; swap items in pointer list
- (setq t1 (nth j ptr_lst)
- t2 (nth (1+ j) ptr_lst)
- ptr_lst (subst t2 -1
- (subst t1 t2
- (subst -1 t1 ptr_lst)
- )
- )
- unsorted T
- ) ;setq
- ) ;if
- (setq j (1+ j))
- ) ;while j
- (setq i (1+ i))
- ) ;while i
- ;-----------------------------------------------------------------------
- ;Build new list using sorted pointers
- (setq count 0 sorted_list nil)
- (while (< count number_items)
- (setq sorted_list
- (append sorted_list ;build updated list
- (list
- (nth
- (nth count ptr_lst) ;pointer
- lst
- )
- )
- )
- count (1+ count)
- ) ;setq
- ) ;while
- sorted_list ;return sorted list
- ) ;progn
- ;else
- nil
- ) ;if
- ) ;defun
- ;;;=======================================================================
- ;;;
- ;;; ssort
- ;;;
- ;;; Modified Shell Sort of List of Values
- ;;; Parameters lst -> list of values
- ;;;
- ;;; Returns -> Sorted list of values
- ;;;
- ;;; Note: This custom shell sort algorithm will handle multiple
- ;;; occurrences of any items. The sort will continue looping
- ;;; when partition size is 1 until no swaps occur.
- ;;;
- (defun ssort (lst /
- number_items partition_size
- number_partitions first_index
- last_index unsorted
- count ptr_lst
- sorted_list i j
- t1 t2
- )
- (if lst
- (progn
- (setq number_items (length lst)
- partition_size number_items
- ptr_lst nil ;pointer list
- count 0
- unsorted T ;assume list is not sorted
- )
- (while (< count number_items)
- (setq ptr_lst (append ptr_lst (list count)) ;built pointer list
- count (1+ count)
- )
- ) ;while
- ;------------------------------------------------------------------
- (while unsorted
- (setq partition_size (fix (/ (1+ partition_size) 2))
- number_partitions (fix (/ number_items partition_size))
- )
- (if (= partition_size 1)
- (setq unsorted nil) ;assume list is sorted
- )
- (if (/= (rem number_items partition_size) 0)
- (setq number_partitions (1+ number_partitions))
- )
- (setq first_index 0
- i 1
- )
- (while (< i number_partitions)
- (setq last_index (+ first_index partition_size))
- (if (> last_index (- number_items partition_size))
- (setq last_index (- number_items partition_size))
- )
- ;loop thru and test (j) to (j+offset) in pointer list
- (setq j first_index)
- (while (< j last_index)
- (if (> (nth (nth j ptr_lst) lst)
- (nth (nth (+ j partition_size) ptr_lst) lst)
- )
- ; then swap items in pointer list
- (setq t1 (nth j ptr_lst)
- t2 (nth (+ j partition_size) ptr_lst)
- ptr_lst (subst t2 -1
- (subst t1 t2
- (subst -1 t1 ptr_lst)
- )
- )
- unsorted T
- ) ;setq
- ) ;if
- (setq j (1+ j))
- ) ;while j
- (setq first_index (+ first_index partition_size)
- i (1+ i)
- )
- ) ;while i
- ) ;while unsorted
- ;------------------------------------------------------------------
- ;Build new list using sorted pointers
- (setq count 0 sorted_list nil)
- (while (< count number_items)
- (setq sorted_list
- (append sorted_list ;build updated list
- (list
- (nth
- (nth count ptr_lst) ;pointer
- lst
- )
- )
- )
- count (1+ count)
- ) ;setq
- ) ;while
- sorted_list ;return sorted list
- ) ;progn
- ;else
- nil
- ) ;if
- ) ;defun
- ;;;========================================================================
|