mirror of
				https://codeberg.org/1414codeforge/gear.git
				synced 2025-06-05 22:09:24 +02:00 
			
		
		
		
	[algo] Add stable sort algorithm, using merge sort.
This commit is contained in:
		
							
								
								
									
										70
									
								
								algo.lua
									
									
									
									
									
								
							
							
						
						
									
										70
									
								
								algo.lua
									
									
									
									
									
								
							| @@ -139,4 +139,74 @@ function algo.bsearchr(array, what, less) | |||||||
|     return lo + ofs |     return lo + ofs | ||||||
| end | end | ||||||
|  |  | ||||||
|  | local function merge(array, lo, mid, hi, less, workspace) | ||||||
|  |     local i, j, k | ||||||
|  |     i = 1 | ||||||
|  |  | ||||||
|  |     -- Copy first half of array to auxiliary array | ||||||
|  |     for j = lo,mid do | ||||||
|  |         workspace[i] = array[j] | ||||||
|  |         i = i + 1 | ||||||
|  |     end | ||||||
|  |  | ||||||
|  |     i = 1 | ||||||
|  |     j = mid + 1 | ||||||
|  |     k = lo | ||||||
|  |     while k < j and j <= hi do | ||||||
|  |         local v = array[j] | ||||||
|  |         local el = workspace[i] | ||||||
|  |  | ||||||
|  |         if less(v, el) then | ||||||
|  |             array[k] = v | ||||||
|  |             j = j + 1 | ||||||
|  |         else | ||||||
|  |             array[k] = el | ||||||
|  |             i = i + 1 | ||||||
|  |         end | ||||||
|  |         k = k + 1 | ||||||
|  |     end | ||||||
|  |  | ||||||
|  |     -- Copy back any remaining elements of first half | ||||||
|  |     for k = k,j-1 do | ||||||
|  |         array[k] = workspace[i] | ||||||
|  |         i = i + 1 | ||||||
|  |     end | ||||||
|  | end | ||||||
|  |  | ||||||
|  | local function mergesort(array, lo, hi, less, workspace) | ||||||
|  |     if hi - lo < 72 then | ||||||
|  |         _insertionsort(array, lo, hi, less) | ||||||
|  |     else | ||||||
|  |         local mid = floor((lo + hi)/2) | ||||||
|  |  | ||||||
|  |         mergesort(array, lo, mid, less, workspace) | ||||||
|  |         mergesort(array, mid + 1, hi, less, workspace) | ||||||
|  |         merge(array, lo, mid, hi, less, workspace) | ||||||
|  |     end | ||||||
|  | end | ||||||
|  |  | ||||||
|  | --- Array stable sort, uses Merge Sort - O(n*log(n)). | ||||||
|  | -- | ||||||
|  | -- Algorithm is a slightly altered version of stable_sort(), | ||||||
|  | -- posted on Lua-L by Steve Fisher on 02 May 2013 22:10:50 | ||||||
|  | -- https://lua-users.org/lists/lua-l/2013-05/msg00038.html | ||||||
|  | -- | ||||||
|  | -- This implementation uses an auxiliary buffer of size O(n/2). | ||||||
|  | -- | ||||||
|  | -- @tparam table array Array to be sorted. | ||||||
|  | -- @tparam[opt=operator <] function less comparison function, takes 2 arguments, | ||||||
|  | --                                  returns true if its first argument is | ||||||
|  | --                                  less than its second argument, | ||||||
|  | --                                  false otherwise. | ||||||
|  | -- @tparam[opt={}] table use an existing workspace buffer instead of allocating one. | ||||||
|  | function algo.stablesort(array, less, workspace) | ||||||
|  |     local n = #array | ||||||
|  |  | ||||||
|  |     less = less or lt | ||||||
|  |     workspace = workspace or {} | ||||||
|  |     workspace[floor((n+1)/2)] = array[1]   -- preallocate some room | ||||||
|  |  | ||||||
|  |     mergesort(array, 1, n, less, workspace) | ||||||
|  | end | ||||||
|  |  | ||||||
| return algo | return algo | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user