简体   繁体   中英

Unable to remove lowest value from linked-list

I created a linked-list in C. I'm trying to create a function that looks at the lowest value in the linked list (which is the head) and the removes the "right-most" instance of that value in the list.

Suppose the linked-list looks like this:

2 -> 2 -> 2 -> 4 -> 5 -> 6

The head in this list is 2. But it's not the head I want to remove. I want to remove the 2 that comes before the 4 (it is the right-most instance of the head).

Here's the function I created to implement this:

double removeLowestValue() {
  struct node *temp;
  struct node *ptr = head;
  double val = ptr->value;
  if(head == tail)
  {
      free(head);
      head = NULL;
      tail = NULL;
  }
  else
  {
      while(ptr->value == ptr->next->value)
      {
          temp = ptr;
          ptr = ptr->next;
          val = ptr->value
      }
      temp->next = NULL;
      temp->next = ptr->next;
      free(ptr);

      return val;
  }
}

Then I tried to test if the function works:

int main() {
  insertNode(18.0);
  insertNode(13.0);
  insertNode(11.0);
  insertNode(11.0);
  insertNode(22.0);

  printf("%d", removeLowestValue());

  return 0;
}

Unfortunately, the program doesn't print out "11" as expected. Matter of fact, it doesn't print anything at all. What's going on here?

EDIT:

Here's how I implemented the insertNode function:

void insertNode(double value) {
  struct node *new_node = create_new_node(value);
  struct node *temp = head;
  struct node *prev;

  if (head == NULL) {
    head = new_node;
    tail = new_node;
  } else {
    while (value > temp->value && temp->next != NULL) {
      prev = temp;
      temp = temp->next;
    }

    if(value < temp->value || value == temp->value)
    {
        /*If the value of the new node equals to the value of temp
         OR if the value of the new node is less than the value of temp,
         then insert the new node right before temp*/

        new_node->next = temp;
        prev->next = new_node;
    }
    else if(value > temp->value)
    {
        temp->next = new_node;
        tail = new_node;
    }
  }
}

your function corrected, of course that supposes the list is sorted :

double removeLowestValue() {
  if (head == NULL)
    return 0; /* ???? */
  else {
    node * ptr = head;
    node * previous = 0; /* the cell before the cell to remove */

    while ((ptr->next != NULL) && (ptr->value == ptr->next->value)) {
      previous = ptr;
      ptr = ptr->next;
    }

    /* ptr is now the cell to remove */

    double val = ptr->value;

    if (ptr == head) {
      /* remove the first cell */
      ptr = head->next;
      free(head);
      head = ptr;
      if (head == NULL)
        /* the list is empty */
        tail = NULL;
    }
    else if (ptr->next == NULL) {
      /* all the values are the same in the list
         ptr is the last cell */
      free(ptr);
      /* previous is now the last cell */
      previous->next = NULL;
      tail = previous;
    }
    else {
      /* ptr is not the first nor the last cell */
      previous->next = ptr->next;
      free(ptr);
    }

    return val;
  }
}

Concerning insertNode :

  • it is better to move the declaration of the variables temp and prev where they are useful, they are useless if head null so at the top of the definition

  • (value < temp->value || value == temp->value) can be just (value <= temp->value) and the else if (...) after can be just an else

  • when (value <= temp->value) prev can be still unset but used for prev->next = new_node , that appends when you insert 13 after 18 in your main . When (temp == head) you have to update head setting it with new_node

So the corrected version can be :

void insertNode(double value) {
  struct node *new_node = create_new_node(value);

  if (head == NULL) {
    head = new_node;
    tail = new_node;
  } else {
    struct node *temp = head;
    struct node *prev = 0; /* = 0 to be sure to have a crash if something wrong */

    while ((value > temp->value) && (temp->next != NULL)) {
      prev = temp;
      temp = temp->next;
    }

    if (value <= temp->value)
    {
        /* insert the new node right before temp*/
        new_node->next = temp;
        if (temp == head)
          head = new_node;
        else
          /* prev was set */
          prev->next = new_node;
    } else {
        /* insert the new node at end */
        temp->next = new_node;
        tail = new_node;
    }
  }
}

Using the additional definitions

typedef struct node {
  double value;
  struct node * next;
} node;

node * create_new_node(double value)
{
  node * r = (node *) malloc(sizeof(node));

  r->value = value;
  r->next = 0;

  return r;
}

int main() {
  insertNode(18.0);
  insertNode(13.0);
  insertNode(11.0);
  insertNode(11.0);
  insertNode(22.0);

  printf("%g\n", removeLowestValue());
  printf("%g\n", removeLowestValue());
  printf("%g\n", removeLowestValue());
  printf("%g\n", removeLowestValue());
  printf("%g\n", removeLowestValue());
  printf("%g\n", removeLowestValue());

  return 0;
}

the execution writes (the last 0 indicate the list is empty)

11
11
13
18
22
0

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM