2010-01-12 4 views
1

Нужно ли использовать BST с обоими ключами и значениями? Я могу реализовать BST, который имеет вызовы методов, такие как следующее, в котором он будет делать сравнение в каждом узле, следует ли обход перейти на левый узел или правый узел, основанный на значении V:Нужно ли реализовать BST с ключами и значениями?

public class BST<V> 
{ 
    public void Insert(V value) 
    { 
     //implementation 
    } 

    public V Remove(V value) 
    { 
     //implementation 
    } 

    //other methods 
} 

или я могу реализовать BST таким образом, что он имеет метод вызывает как следующий, в котором ключи K являются сравнением определения того, чтобы пройти к левому узлу или правому узел:

public class BST<K key, V value> 
{ 
    public void Insert(K key, V value) 
    { 
     //implementation 
    } 

    //which of the following would then be the appropriate method signature? 
    public V Remove(K key) 
    { 
     //implementation 
    } 
    //or? 
    public V Remove(V Value) 
    { 
     //implementation 
    } 

    //other methods 
} 

ответ

2

Не использовать ключ, но только значение в порядке. Однако, если вы сделаете это, дерево станет неизменным. Изменение значения больше не безопасно, так как это приведет к дисбалансу дерева. Вам нужно будет обеспечить это, предоставив только свойство getter для значения узла.

+0

Учитывая, что вы бы рекомендовали в качестве общего решения BST, которое содержит ключи и значения? –

+0

Определенно, да. Вот как работают классы System.Collection. –

+0

Вы уверены, что не думаете об ароматах IDictionary? Реализации интерфейса ICollection в .NET не обеспечивают прямого доступа для изменения элемента, тогда как IDictionary предоставляют доступ на основе индекса/ключа. ICollection предоставляет только Add и Remove для доступа к элементу. –

0

Если структура данных общего назначения Я бы предложил использовать API на основе ключа (поскольку вы не знаете заранее соотношение между ключами и значениями) с IComparable constr на TKey. Если это конкретная реализация для конкретного случая, когда ключ также является значением (например, BST используется для определения того, содержит ли он указанный ключ или нет), я бы предложил использовать API на основе ключевых слов.

+1

Если кто-то разрабатывает его для общего назначения, имеет смысл не развивать отношения ключ/значение, так что общий тип может указывать KeyValuePair? –

+0

Но KeyValuePair не предоставляет явных средств для сравнения ни ключей, которые он держит (у него нет ограничений на клавиши), ни самих пар (KeyValuePair не реализует IComparable ). Конечно, вы можете использовать такие вещи, как Comparer .Default, но все же это делает API неопределенным, так как трудно сказать, как будут сравниваться пары. –

0

Это зависит от того, что вам действительно нужно. Если вам нужна ассоциативная структура данных, реализация на основе ключевого значения - это то, что вам нужно реализовать. В противном случае, если вы просто кладете элементы в сортированную коллекцию, я не вижу необходимости иметь отдельный ключ для каждого элемента. Просто убедитесь, что все элементы реализуют Comparable или вы можете передать пользовательскую реализацию Comparator (например, в TreeSet/TreeMap) или любую четко определенную схему наличия total ordering элементов BST.

0

Нет, структуры данных, которые нуждаются в ключах для работы, не требуют ничего. Это зависит от того, как вы хотите его реализовать. В большинстве случаев использование системы с ключом-парой является наиболее удобным, но в некоторых реализациях вы можете позволить пользователю структуры данных указать функцию сравнения и просто иметь в каждом узле «значение» (экземпляр определяемого пользователем класса). Этот класс может содержать ключ среди прочего, но вам не нужно знать формат класса, потому что пользовательская функция сравнения будет заботиться обо всем.

Пример, который я могу придумать, где это используется, - in the Windows kernel.