Показать сообщение отдельно
Старый 28.09.2011, 11:07   #4
Randomize
[object Object]
 
Аватар для Randomize
 
Регистрация: 01.08.2008
Адрес: В России
Сообщений: 4,355
Написано 2,471 полезных сообщений
(для 6,853 пользователей)
Сообщение Ответ: [Вопрос] Оптимизация поиска в листе

Сообщение от Greymem Посмотреть сообщение
То есть все равно придется вести два списка?
Нет. TMap это и есть эти самые 2 списка.

Сообщение от Greymem Посмотреть сообщение
Но что у нас с быстродействием?
Заглянем в код:
	Method _FindNode:TNode( key:Object )
		Local node:TNode=_root
		While node<>nil
			Local cmp=key.Compare( node._key )
			If cmp>0
				node=node._right
			Else If cmp<0
				node=node._left
			Else
				Return node
			EndIf
		Wend
		Return node
	End Method
Фактически тут происходит тоже самое что и у тебя во "втором способе".
За единственным исключением что тут нет листов в принципе. Тут структура сама по себе ориентирована на список "ключ":"Значение"
Вообще по чаще заглядывай в модули:
BlitzMax\mod\brl.mod\map.mod
Там по коду можно сообразить что да как работает.

Ну и кратенький пример использования:
SuperStrict
Framework brl.basic
Import brl.map
Import brl.random

' произвольный тип
Type MyObj
	Field i:Int = 33
	Field z:Int = 77
	
	' для отчётности
	Method ToString:String()
		Return "my values: " + i + " " + z
	EndMethod
EndType

Local map:TMap = New TMap



' Заполняем рандомными объектами нашу "карту"
For Local i:Int = 0 Until 100
	
	Local obj:MyObj = New MyObj
	obj.i = Rand(0, 100)
	obj.z = Rand(10, 20)
	
	map.Insert("Object" + i, obj)
Next



' Теперь попробуем проверить существует ли объект с определённым ключом
Print "Object #1: " + map.Contains("Object1")
Print "Object #33: " + map.Contains("Object33")
Print "Object #33: " + map.Contains("Object33")
Print "Object #155: " + map.Contains("Object155")

' Попрбуем извлеч
Print "Object77: " + MyObj(map.ValueForKey("Object77")).ToString()
Print "Object12: " + MyObj(map.ValueForKey("Object12")).ToString()
Print "Object5: " + MyObj(map.ValueForKey("Object5")).ToString()
' Но так делать опастно! Лучше сначала проверять на наличе объекта по ключу или делать так:

Local _object:MyObj = MyObj(map.ValueForKey("Object35"))

If _object Then ' Если объект нашёлся то код выполнится
	Print _object.ToString()
EndIf

' Смоделируем ошибочную ситуацию
_object:MyObj = MyObj(map.ValueForKey("Object935"))

If _object Then
	Print _object.ToString()
Else
	Print "Cant find"
EndIf
Чтоб всё шустро работало просто не производи поиск по таблице постоянно в цикле. Лучше ищи один раз и заноси в переменную.
__________________
Retry, Abort, Ignore? █
Intel Core i7-9700 4.70 Ghz; 64Gb; Nvidia RTX 3070
AMD Ryzen 7 3800X 4.3Ghz; 64Gb; Nvidia 1070Ti
AMD Ryzen 7 1700X 3.4Ghz; 8Gb; AMD RX 570
AMD Athlon II 2.6Ghz; 8Gb; Nvidia GTX 750 Ti
(Offline)
 
Ответить с цитированием
Эти 3 пользователя(ей) сказали Спасибо Randomize за это полезное сообщение:
Greymem (28.09.2011), moka (28.09.2011), NitE (28.09.2011)