Интересная идиома связанного списка C

Я заставил это работать, добавив измененный обработчик событий, а затем изменив регистрацию свойства зависимостей для ссылки на него. Мой рабочий код:

public partial class MyBox : UserControl
{
    public MyBox()
    {
        InitializeComponent();
    }

    public bool Rounded
    {
        get { return (bool)GetValue(RoundedProperty); }
        set { SetValue(RoundedProperty, value); }
    }

    public static readonly DependencyProperty RoundedProperty = DependencyProperty.Register("Rounded", typeof(bool), typeof(MyBox), new PropertyMetadata(false, RoundedChanged));

    private static void RoundedChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
    {
        bool value = (bool)e.NewValue;
        MyBox thisMyBox = (MyBox)sender;

        // Hide/show the edges
        thisMyBox.edgeRounded.Visibility = (value ? Visibility.Visible : Visibility.Hidden);
        thisMyBox.edgePolygon.Visibility = (value ? Visibility.Hidden : Visibility.Visible);
    }
}
11
задан elifiner 1 December 2008 в 22:19
поделиться

8 ответов

Я использовал подобный этому для вставки в двоичное дерево. Поскольку при итерации дерева, Вы обычно останавливаетесь, когда Ваш указатель становится NULL (Вы убежали дерево).

Таким образом для вставки у Вас есть 3 опции,

1: используйте переменную, которая отслеживает предыдущее значение Вашего указателя итерации.

2: остановитесь, когда указатель, за которым Вы следовали бы, является НУЛЕВЫМ, прежде чем Вы будете следовать за ним, работы, но немного менее изящный, по-моему.

3: или более изящным решением является просто использование указатель на указатель, таким образом, можно просто сделать: *it = new_node(); и это добавит его где NULL используемый, чтобы быть в Вашем дереве.

Для связанного списка, в то время как этот код работает приятно, я обычно просто использую двунаправленный связанный список, который делает его тривиальным для вставки в любом местоположении.

6
ответ дан 3 December 2019 в 03:05
поделиться

Я сказал бы, что идиома является "видом кода, который дал 'c' дурную славу"

  • Неоправданно умный
  • Неоправданно компактный
  • Удивительные побочные эффекты на вызывающей стороне
  • Никакая обработка ошибок на malloc
  • Только работы для американских английских строк
8
ответ дан 3 December 2019 в 03:05
поделиться

Я не вижу ничего, что я назвал бы идиомой по сути. Похоже на стандартное кодирование для того, когда Вы имеете дело с datastructures в C.

Моя единственная жалоба была бы то, что указатель вызывающих сторон (*r) изменяется. В зависимости от использования функции я ожидал бы, что это - неожиданный побочный эффект. Помимо удаления неожиданного побочного эффекта, с помощью локальной переменной, чтобы играть роль *r сделал бы код более читаемым.

4
ответ дан 3 December 2019 в 03:05
поделиться

Вместо того, чтобы возвратить значение нового узла как в / параметре, Вы - более обеспеченное наличие, которое можно быть возвращаемым значением функции. Это упрощает и код вызова и код в функции (можно избавиться от всей той ужасной двойной косвенности).

record* insert_sorted(const record* head, const char* value)

Вы пропускаете обработку ошибок для malloc/strdup провальный случай btw.

1
ответ дан 3 December 2019 в 03:05
поделиться

Какова была бы идиома здесь? Конечно, не реализация связанного списка. Использование указателя на конструкцию указателя? Компактный цикл?

Лично я использовал бы возвращаемое значение указателя вместо того, чтобы воздействовать на входное значение. Поскольку наблюдение этого типа входных данных позвонило бы в звонок, который заставляет меня скопировать свое значение прежде, чем вручить его Вашей функции.

3
ответ дан 3 December 2019 в 03:05
поделиться

Это - известная вещь - двойное повторение указателя (это - мое имя его, я не знаю официальное название). Цель состоит в том, чтобы смочь определить положение в единственном связанном списке и затем вставить перед тем положением (вставка после того, как это будет тривиально). Реализованный наивно, это требует двух указателей (текущий и предыдущий) и специальный код для начала списка (когда предыдущий == ПУСТОЙ УКАЗАТЕЛЬ).

Код путем, который я обычно пишу этому, является чем-то вроде

void insertIntoSorted(Element *&head, Element *newOne)
{
  Element **pp = &head;
  Element *curr;
  while ((curr = *pp) != NULL && less(curr, newOne)) {
    pp = &(pp->next);
  }
  newOne->next = *pp;
  *pp = newOne;
}

Обновление:

Я имею, забыл theother цель для этого приема - более важный. Это используется для удаления элементов из единственных связанных списков:

// returns deleted element or NULL when key not found
Element *deleteFromList(Element *&head, const ElementKey &key)
{
  Element **pp = &head;
  Element *curr;
  while ((curr = *pp) != NULL && !keyMatches(curr, key)) {
    pp = &(pp->next);
  }
  if (curr == NULL) return NULL;
  *pp = (*pp)->next; // here is the actual delete
  return curr;
}
3
ответ дан 3 December 2019 в 03:05
поделиться

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

Для запуска они всегда вдвойне связываются, так как это делает обход в обоих направлениях легче, и для обработки, и вставьте/удалите операции.

'Пустой' список на самом деле состоит из двух узлов, головы и хвоста. Путем выполнения этого, вставляет и удаляет, не должны волноваться о том, является ли узел, который они удаляют, головой или хвостом, они могут просто предположить, что это - средний узел.

Вставка нового узла y перед узлом x затем становится простым:

x -> prev -> next = y
y -> next = x
y -> prev = x -> prev
x -> prev = y

Удаление узла x является простым:

x -> prev -> next = x -> next
x -> next -> prev = x -> prev
free x

Обход корректируется для игнорирования посторонней головы и хвоста:

n = head -> next
while n != tail
    process n
    n = n -> next

Это все подачи для создания кода намного легче понять без всей специальной обработки пограничных случаев, за счет нескольких узлов памяти.

2
ответ дан 3 December 2019 в 03:05
поделиться

Для ответа на исходный вопрос это известно как указатель центральный подход вместо наивного узла центральный подход. Глава 3 "Усовершенствованных Методов программирования" Rex Barzee, доступным по amazon.com, включает намного лучшую реализацию в качестве примера указателя центральный подход.

1
ответ дан 3 December 2019 в 03:05
поделиться
Другие вопросы по тегам:

Похожие вопросы: