瀏覽代碼

Added new TArrayList constructors.
Added TArrayList Sort().

woollybah 6 年之前
父節點
當前提交
f253f1cbca
共有 3 個文件被更改,包括 254 次插入0 次删除
  1. 42 0
      collections.mod/doc/tarraylist_sort.bmx
  2. 55 0
      collections.mod/list.bmx
  3. 157 0
      collections.mod/sort.bmx

+ 42 - 0
collections.mod/doc/tarraylist_sort.bmx

@@ -0,0 +1,42 @@
+SuperStrict
+
+Framework brl.collections
+Import brl.standardio
+Import brl.Random
+
+SeedRnd(42)
+
+Local numbers:TArrayList<Int> = New TArrayList<Int>
+
+For Local i:Int = 0 Until 20
+	numbers.Add(Rand(0, 100))
+Next
+
+Print "Unsorted:"
+For Local num:String = EachIn numbers
+	Print num
+Next
+
+numbers.Sort()
+
+Print "~nSorted:"
+For Local num:String = EachIn numbers
+	Print num
+Next
+
+Local reverse:TReverseComparator<Int> = New TReverseComparator<Int>
+
+numbers.Sort(reverse)
+
+Print "~nReversed:"
+For Local num:String = EachIn numbers
+	Print num
+Next
+
+Type TReverseComparator<T> Implements IComparator<T>
+
+	Method Compare:Int(a:T, b:T)
+		Return DefaultComparator_Compare(b, a)
+	End Method
+
+End Type

+ 55 - 0
collections.mod/list.bmx

@@ -2,6 +2,7 @@ SuperStrict
 
 Import "collection.bmx"
 Import "errors.bmx"
+Import "sort.bmx"
 
 Interface IList<T> Extends ICollection<T>
 
@@ -35,6 +36,35 @@ Public
 		data = New T[initialCapacity]
 	End Method
 
+	Rem
+	bbdoc: Creates a new #TArrayList initialised by @array.
+	End Rem
+	Method New(array:T[])
+		initialCapacity = 16
+		If array Then
+			initialCapacity = Max(initialCapacity, array.length)
+		End If
+		data = New T[initialCapacity]
+		
+		If data Then
+			For Local element:T = EachIn array
+				Add(element)
+			Next
+		End If
+	End Method
+
+	Rem
+	bbdoc: Creates a new #TArrayList initialised by @iterable.
+	End Rem
+	Method New(iterable:IIterable<T>)
+		New(16)
+		If iterable Then
+			For Local value:T = EachIn iterable
+				Add(value)
+			Next
+		End If
+	End Method
+
 	Rem
 	bbdoc: Returns an iterator that iterates through the #TList.
 	End Rem
@@ -244,6 +274,31 @@ Public
 		data[size] = Null
 	End Method
 	
+	Rem
+	bbdoc: Sorts the elements in the entire #TArrayList using the specified comparator, or the default if #Null.
+	End Rem
+	Method Sort(comparator:IComparator<T> = Null)
+		' introsort
+		If size < 2 Then
+			Return
+		End If
+		
+		Local depth:Int
+		Local n:Int = size
+		While n >= 1
+			depth :+ 1
+			n = n / 2
+		Wend
+		
+		depth :* 2
+		
+		If comparator Then
+			New TComparatorArraySort<T>(comparator).Sort(data, 0, size - 1, depth)
+		Else
+			New TArraySort<T>().Sort(data, 0, size - 1, depth)
+		End If
+	End Method
+	
 	Rem
 	bbdoc: Sets the capacity to the actual number of elements in the #TArrayList.
 	about: This method can be used to minimize a collection's memory overhead if no new elements will be added to the collection. 

+ 157 - 0
collections.mod/sort.bmx

@@ -0,0 +1,157 @@
+SuperStrict
+
+Type TComparatorArraySort<T> Extends TArraySort<T>
+
+	Field comparator:IComparator<T>
+	
+	Method New(comparator:IComparator<T>)
+		Self.comparator = comparator
+	End Method
+
+	Method DoCompare:Int(a:T, b:T)
+		Return comparator.Compare(a, b)
+	End Method
+
+End Type
+
+Type TArraySort<T>
+
+	Method DoCompare:Int(a:T, b:T)
+		Return DefaultComparator_Compare(a, b)
+	End Method
+
+	Method Sort(array:T[], low:Int, high:Int, depthLimit:Int)
+
+		While high > low
+		
+			Local partitionSize:Int = high - low + 1
+			If partitionSize <= 16 Then
+				If partitionSize = 1 Then
+					Return
+				End If
+				
+				If partitionSize = 2 Then
+					SwapIfGreater(array, low, high)
+					Return
+				End If
+				
+				If partitionSize = 3 Then
+					SwapIfGreater(array, low, high - 1)
+					SwapIfGreater(array, low, high)
+					SwapIfGreater(array, high - 1, high)
+					Return
+				End If
+				
+				InsertionSort(array, low, high)
+				Return
+			End If
+		
+			If Not depthLimit Then
+				Heapsort(array, low, high)
+				Return
+			End If
+			
+			depthLimit :- 1
+			
+			Local pivot:Int = PickPivotAndPartition(array, low, high)
+			Sort(array, pivot + 1, high, depthLimit)
+			high = pivot - 1
+		Wend
+	End Method
+
+	Method SwapIfGreater(array:T[], a:Int, b:Int)
+		If a <> b Then
+			If DoCompare(array[a], array[b]) > 0 Then
+				Local tmp:T = array[a]
+				array[a] = array[b]
+				array[b] = tmp
+			End If
+		End If
+	End Method
+
+	Method Swap(array:T[], a:Int, b:Int)
+		If a <> b Then
+			Local tmp:T = array[a]
+			array[a] = array[b]
+			array[b] = tmp
+		End If
+	End Method
+	
+	Method InsertionSort(array:T[], low:Int, high:Int)
+		For Local i:Int = low Until high
+			Local n:Int = i
+			Local tmp:T = array[i + 1]
+			While n >= low And DoCompare(tmp, array[n]) < 0
+				array[n + 1] = array[n]
+				n :- 1
+			Wend
+			array[n + 1] = tmp
+		Next
+	End Method
+	
+	Method HeapSort(array:T[], low:Int, high:Int)
+		Local n:Int = high - low + 1
+		Local i:Int = n / 2
+		While i >= 1
+			DownHeap(array, i, n, low)
+			i :- 1
+		Wend
+		i = n
+		While i > 1
+			Swap(array, low, low + i - 1)
+			DownHeap(array, 1, i - 1, low)
+			i :- 1
+		Wend
+	End Method
+
+	Method DownHeap(array:T[], i:Int, n:Int, low:Int)
+		Local down:T = array[low + i - 1]
+		Local child:Int
+		While i <= n / 2
+			child = 2 * i
+			If child < n And DoCompare(array[low + child - 1], array[low + child]) < 0 Then
+				child :+ 1
+			End If
+			If DoCompare(down, array[low + child - 1]) >= 0 Then
+				Exit
+			End If
+			array[low + i - 1] = array[low + child - 1]
+			i = child
+		Wend
+		array[low + i - 1] = down
+	End Method
+
+	Method PickPivotAndPartition:Int(array:T[], low:Int, high:Int)
+		Local middle:Int = low + ((high - low) / 2)
+		
+		SwapIfGreater(array, low, middle)
+		SwapIfGreater(array, low, high)
+		SwapIfGreater(array, middle, high)
+
+		Local pivot:T = array[middle]
+		Swap(array, middle, high - 1)
+		Local lft:Int = low
+		Local rgt:Int = high - 1
+		
+		While lft < rgt
+			lft :+ 1
+			While DoCompare(array[lft], pivot) < 0
+				lft :+ 1
+			Wend
+			rgt :- 1
+			While DoCompare(pivot, array[rgt]) < 0
+				rgt :- 1
+			Wend
+
+			If lft >= rgt Then
+				Exit
+			End If
+
+			Swap(array, lft, rgt)
+		Wend
+
+		Swap(array, lft, high - 1)
+		Return lft
+	End Method
+	
+End Type