Я забыл добавить, что если у вас есть представление о размере набора данных и распределении ключей, вы можете использовать радикальную сортировку, которая будет O (N). Чтобы получить представление о радикальной сортировке, рассмотрим случай, когда вы сортируете, скажем, числа, более или менее распределенные между 0, 100 000. Затем вы просто создаете что-то похожее на хеш-таблицу, скажем, массив из 100 000 списков, и добавляете каждое число в корзину. Вот реализация, которую я написал за несколько минут, которая генерирует некоторые случайные данные, сортирует их и распечатывает случайный сегмент. Время выполнения для массива из 100 000 целых чисел составляет менее 1 с.
Опция Строгое Включено
Опция Явная Вкл.
Модуль Модуль1
Private Const MAX_SIZE As Integer = 100000
Private m_input(MAX_SIZE) As Integer
Private m_table(MAX_SIZE) As List(Of Integer)
Private m_randomGen As New Random()
Private m_operations As Integer = 0
Private Sub generateData()
' fill with random numbers between 0 and MAX_SIZE - 1
For i = 0 To MAX_SIZE - 1
m_input(i) = m_randomGen.Next(0, MAX_SIZE - 1)
Next
End Sub
Private Sub sortData()
For i As Integer = 0 To MAX_SIZE - 1
Dim x = m_input(i)
If m_table(x) Is Nothing Then
m_table(x) = New List(Of Integer)
End If
m_table(x).Add(x)
' clearly this is simply going to be MAX_SIZE -1
m_operations = m_operations + 1
Next
End Sub
Private Sub printData(ByVal start As Integer, ByVal finish As Integer)
If start < 0 Or start > MAX_SIZE - 1 Then
Throw New Exception("printData - start out of range")
End If
If finish < 0 Or finish > MAX_SIZE - 1 Then
Throw New Exception("printData - finish out of range")
End If
For i As Integer = start To finish
If m_table(i) IsNot Nothing Then
For Each x In m_table(i)
Console.WriteLine(x)
Next
End If
Next
End Sub
' run the entire sort, but just print out the first 100 for verification purposes
Private Sub test()
m_operations = 0
generateData()
Console.WriteLine("Time started = " & Now.ToString())
sortData()
Console.WriteLine("Time finished = " & Now.ToString & " Number of operations = " & m_operations.ToString())
' print out a random 100 segment from the sorted array
Dim start As Integer = m_randomGen.Next(0, MAX_SIZE - 101)
printData(start, start + 100)
End Sub
Sub Main()
test()
Console.ReadLine()
End Sub
Конечный модуль
Время началось = 15.06.2009 16:04:08
Время закончено = 15.06.2009 16:04:08 Количество операций = 100000
21429
21430
21430
21431
21431
21432
21433
21435
21435
21435
21436
21437
21437
21439
21441
...