Из структуры, указатель на NULL и обратно - PullRequest
0 голосов
/ 01 мая 2020
typedef struct Element 
{
    int number;
    struct Element *right;
    struct Element *left;
} Element;

Element *newElement;
Element *head;
Element *pos;     
Element *current; 

void insert_Element()
{
    newElement = malloc(sizeof(Element));

    if (head==NULL)    
    {
      head = newElement;
      current = newElement;
      current->right = pos;
      //pos->left = current;
    }
}

Заголовок списка двойных связей должен иметь указатель на следующий (right) элемент (который является NULL, но также pos). Это работает нормально, но указатель назад (left) из pos / NULL не работает. Над чем я работал; Это вообще возможно? Заранее спасибо:)

Ответы [ 2 ]

2 голосов
/ 01 мая 2020

Текущая версия функции insert_Element не работает, если head не равен NULL и pos не является NULL и не установлен элемент left нового элемента. Назначение переменной pos не указано, но, похоже, используется для указания на элемент, перед которым должен быть вставлен новый элемент. Мы могли бы использовать pos == NULL, чтобы указать, что новый элемент должен быть помещен в конец списка. Вот версия, которая делает это:

void insert_Element(void)
{
    newElement = malloc(sizeof(Element));
    if (newElement == NULL)
    {
        return;
    }
    newElement->right = pos;
    if (pos != NULL)
    {
        /* insert before pos */
        newElement->left = pos->left;
        pos->left = newElement;
    }
    else if (head != NULL)
    {
        /* add to end of list */
        current = head;
        while (current->right != NULL)
        {
            current = current->right;
        }
        newElement->left = current;
        current->right = newElement;
    }
    else
    {
        /* add to empty list */
        newElement->left = NULL;
    }
    if (pos == head)
    {
        /* make it the start of the list */
        head = newElement;
    }
    /* make it the 'current' element */
    current = newElement;
}

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

Element *insert_Element(Element **phead, Element *pos)
{
    Element *newElement = malloc(sizeof(Element));
    if (newElement == NULL)
    {
        return NULL;
    }
    newElement->right = pos;
    if (pos != NULL)
    {
        /* insert before pos */
        newElement->left = pos->left;
        pos->left = newElement;
    }
    else if (*phead != NULL)
    {
        /* add to end of list */
        Element *current = *phead;
        while (current->right != NULL)
        {
            current = current->right;
        }
        newElement->left = current;
        current->right = newElement;
    }
    else
    {
        /* add to empty list */
        newElement->left = NULL;
    }
    if (pos == *phead)
    {
        /* make it the start of the list */
        *phead = newElement;
    }
    return newElement;
}
0 голосов
/ 01 мая 2020

Возможно, вам просто нужно выделить Element *pos. На самом деле pos равен NULL и логически не имеет указателя влево или вправо, это похоже на поиск туалета в доме, который не существует.

...