我有以下链表实现:
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。
答案 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 */
}