在链表中的特定元素后添加元素并删除第一个元素

时间:2014-09-29 08:41:31

标签: c++

我努力解决这个问题但只能部分解决它。

我在这个方法中的问题是我需要在另一个元素之后添加一个元素:

示例:add 5 1

5是链接列表中的元素,但我想在5之后添加1。

示例:让链接列表包含以下元素:2 3 7

我调用方法在3 add 3 1之后添加1,因此结果假定为2 3 1 7,但是使用我的方法,结果为2 1 3 7,这是我的问题。

第二个问题是我无法处理第一个元素:

示例:add 2 1

它就像第一个元素不存在一样:

void addNodeAtPos(link *head, int pos,int addelement)
{
  link prev=NULL;

  link curr =*head;

  link newNode = (link)malloc(sizeof(node));

  newNode->data = addelement;


    while(curr->next != NULL )
    {

              prev = curr;
        curr = curr->next;


         if(curr->data == pos)
    {

        newNode->next = curr;
        prev->next = newNode;

        break;
    }
    }

    }

我的问题是我无法删除第一个元素:

void deletenode(link *head,int s){

    bool found = false;

    node *curr = *head, *prev=NULL;

    while(curr != NULL){

        // match found, delete
        if(curr->data == s){

            found = true;
            // found at top

            if(prev == NULL){

                link temp = *head;

                curr->next= prev;
                delete(temp);
                // found in list - not top
            }else{
                prev->next = curr->next;
                delete(curr);
            } }
        // not found, advance pointers
       if(!found){
            prev = curr;
            curr = curr->next; }
        // found, exit loop
        else curr = NULL; }




     }

2 个答案:

答案 0 :(得分:3)

这是第一个问题的解决方案

if(curr->data == pos)
{
  // tempNode = curr->next;
  // improvement as suggested by @Rerito
  newNode->next = curr->next;
  curr->next = newNode;
  break;
}

答案 1 :(得分:1)

您似乎正在使用非循环双向链表。因此,列表的两端都标有NULL。现在,在我看来,你以非常C语言的方式使用C ++ ...(NULL不会在C ++中使用,有nullptr关键字。)

假设您使用C而不是C ++,我将处理您的问题。

// Note that I pass a link **ptr, NOT a link *ptr ...
void addNodeAtPos(link **head, int pos, int addelement) {
    // I am assuming head will be a valid pointer, if not, please add the appropriate checks.
    link *newNode = NULL, *cur = *head;
    if (NULL == (newNode = malloc(sizeof(link)))
        return;
    newNode->data = addelement;
    while (cur != NULL) {
        if (cur->data == pos || NULL == cur->next) {
            newNode->next = cur->next;
            newNode->prev = cur; // remove this line if there is no prev pointer.
            cur->next = newNode;
            if (NULL != newNode->next) { // remove this if clause if there is no prev pointer
                newNode->next->prev = newNode;
            }
            break;
        }
        cur = cur->next;
    }
}

如果找不到“位置”,你没有指定你应该做什么,我假设你只是在这种情况下在列表末尾添加元素。

现在,考虑到删除第一个元素的问题:

void deleteNode(link **head, int el)
{
    // I assume you wont pass a `NULL` ptr as @head
    link *cur = *head, *prev = NULL;
    while (cur != NULL) {
        if (cur->data == el) {
            next = cur->next;
            prev = cur->prev;
            free(cur);
            if (NULL != next)
               next->prev = prev;
            if (NULL != prev)
                prev->next = next;
            else
                *head = next;
            break;
        }
        cur = cur->next;
    }
}

为什么需要传递link **head而不是link *head?因为当你删除列表的头部时,必须确保它不再被访问,因此你需要更新你在别处使用的头部指针。这是上述函数中*head = next;语句中的内容。

如果您使用单链表(仅指向下一个元素的指针,而不是前一个元素),则解决方案将变为以下内容:

void deleteNode(link **head, int el)
{
    // I assume you wont pass a `NULL` ptr as @head
    link *cur = *head, *prev = NULL, *next = NULL;
    while (cur != NULL) {
        if (cur->data == el) {
            if (NULL != prev)
                prev->next = cur->next;
            else
                *head = cur->next;
            free(cur);
            break;
        }
        prev = cur;
        cur = cur->next;
    }
}