如何在两个索引之间删除链表的节点?

时间:2016-12-25 12:23:06

标签: c linked-list

我有以下链表实现:

struct _node {
    char *string;
    struct _node *next;
}

struct _list {
    struct _node *head;
    struct _node *tail;
}

我想做以下功能:

void deleteList(struct _list *list, int from, int to) {
    int i;

    assert(list != NULL);

    // I skipped error checking for out of range parameters for brevity of code

    for (i = from; i <= to; i++) {
        deleteNode(list->head, i);
    }
}

//我使用此链接列表运行此函数:[First]->[Second]->NULL

像这样deleteNodes(list, 1, 1)删除第二行并得到 [First]->[Second]->NULL但当我使用此输入deleteList(list, 0, 1)运行此[First]->[Second]->[Third]->NULL时,我会遇到段错误。

这是我的deleteNode函数

void deleteNode(struct _node *head, int index) {
    if (head == NULL) {
        return;
    }

    int i;
    struct _node *temp = head;

    if (index == 0) {
        if (head->next == NULL) {
            return;
        }
        else {
            head = head->next;
            free(head);
            return;
        }
    }

    for (i = 0; temp!=NULL && i<index-1; i++) {
        temp = temp->next;
    }

    if (temp == NULL || temp->next == NULL) {
        return;
    }

    Link next = temp->next->next;

    free(temp->next);

    temp->next = next;
}

如果from或to = 0:

,我写了一个单独的函数来删除链表的头部
void pop(struct _node *head) {
    if (head == NULL) {
        return;
    }

    struct _node *temp = head;
    head = head->next;
    free(temp);
}

但它给了我seg故障或内存错误Abort trapL 6。

2 个答案:

答案 0 :(得分:1)

只使用一个struct,一个节点就可以了。

struct node {
    char *string;
    struct node *next;
};

如果你不根据列表的变化长度调整索引,那么你在两个索引之间删除元素的循环不会删除正确的元素。而且你还必须返回列表的新头。

struct node *deleteList(struct node *head, unsigned from, unsigned to) {
    unsigned i;
    unsigned count = 0;
    for (i = from; i <= to; i++) {
        head = delete_at_index(head, i - count);
        count++;
    }
    return head;
}

帮助功能delete_at_index如下所示。

struct node *delete_at_index(struct node *head, unsigned i) {
    struct node *next;

    if (head == NULL)
        return head;

    next = head->next;

    return i == 0
           ? (free(head), next)                                 /* If i == 0, the first element needs to die. Do it. */
           : (head->next = delete_at_index(next, i -
                                                 1), head); /* If it isn't the first element, we recursively check the rest. */
}

完整的程序如下。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

struct node {
    char *string;
    struct node *next;
};

void freeList(struct node *head) {
    struct node *tmp;

    while (head != NULL) {
        tmp = head;
        head = head->next;
        free(tmp->string);
        free(tmp);
    }

}

struct node *delete_at_index(struct node *head, unsigned i) {
    struct node *next;

    if (head == NULL)
        return head;

    next = head->next;

    return i == 0
           ? (free(head), next)                                 /* If i == 0, the first element needs to die. Do it. */
           : (head->next = delete_at_index(next, i -
                                                 1), head); /* If it isn't the first element, we recursively check the rest. */
}

struct node *deleteList(struct node *head, unsigned from, unsigned to) {
    unsigned i;
    unsigned count = 0;
    for (i = from; i <= to; i++) {
        head = delete_at_index(head, i - count);
        count++;
    }
    return head;
}

void pushvar1(struct node **head_ref, char *new_data) {
    struct node *new_node = malloc(sizeof(struct node));
    new_node->string = strdup(new_data);
    new_node->next = (*head_ref);
    (*head_ref) = new_node;
}

void printListvar1(struct node *node) {
    while (node != NULL) {
        printf(" %s ", node->string);
        node = node->next;
    }
    printf("\n");
}

int main(int argc, char **argv) {
    struct node *head = NULL;
    for (int i = 0; i < 5; i++) {
        char str[2];
        sprintf(str, "node%d", i);
        pushvar1(&head, str);
    }

    puts("Created Linked List: ");
    printListvar1(head);
    head = deleteList(head, 0, 2);
    puts("Linked list after deleted nodes from index 0 to index 2: ");
    printListvar1(head);
    freeList(head);
    return 0;
}

测试

Created Linked List: 
 node4  node3  node2  node1  node0 
Linked list after deleted nodes from index 0 to index 2: 
 node1  node0 

答案 1 :(得分:1)

每个编程问题都可以通过添加额外的间接级别来解决:使用指向指针的指针......

unsigned deletefromto(struct node **head, unsigned from, unsigned to)
{
unsigned pos,ret;
struct node *this;

for (pos=ret=0; this = *head;pos++) {
        if (pos < from) { head = &(*head)->next; continue; }
        if (pos > to) break;
        *head = this->next;
        free(this);
        ret++;
        }
return ret; /* nuber of deleted nodes */
}