1

我正在尝试在这里使用 add_to_front 函数实现 sequence_insert_at

之前的一切

typedef struct sequence *Sequence;

是从另一个 c 文件粘贴的。

void sequence_insert_at(Sequence s, int pos, int item)
{
    struct node* temp = s->lst;
    for(; pos > 0; --pos)
    {
        temp = temp->rest;
    }
    add_to_front(&temp, item);
    ++s->length;
    if(!temp->rest)
    {
        s->end = temp;
    }
    //s->lst = temp;
}

我不知道为什么我不断收到运行时错误。如果我克隆 s->lst 并遍历克隆,我不会修改指向 s 中节点的指针,但是如果我更改 temp,s->lst 应该有反映的变化,因为节点仍然是链接的。关于如何解决这个问题的任何想法?我尝试在遍历后创建另一个在 temp 之前的节点,然后设置它->rest = temp,但这也失败了。

4

1 回答 1

2

可以发现以下错误,但到目前为止只能运行主要功能

new_sequence不初始化Sequence它创建的任何东西。lst访问时未初始化sequence_insert_at

struct node* temp = s->lst;

这里应该是什么样子

Sequence new_sequence()
{
    Sequence s = malloc(sizeof(struct sequence));
    if(!s)
    {
        printf("Out of memory. Can't allocate s\n");
        exit(EXIT_FAILURE);
    }
    s->lst = malloc(sizeof(struct node));
    if(! s->lst) {
        printf("Out of memory. Can't allocate lst\n");
    }
    s->lst->rest = NULL;
    s->length = 0;
    return s;
}

s->lst->rest必须设置为NULL,这说明列表中没有更多元素,并且不会end过时。

struct sequence
{
    struct node* lst;
    int length;
};

您应该将序列本身传递给您的函数,而不是指向序列中某些内部数据的指针。

add_to_front(&temp, item);

您的sequence_insert_at函数应该是可以处理任何位置的函数,add_to_front()因此更容易调用位置0add_to_front()并且您可以在一个函数中完成孔工作,而不是这里一半和那里一半。

void sequence_insert_at(Sequence s, int pos, int item)
{
    if(s && pos <= s->length) {
        print_sequence(s);
        struct node *newnode = malloc(sizeof(struct node));
        if (newnode == NULL) {
            printf("ERROR! add_to_front ran out of memory!\n");
            exit(EXIT_FAILURE);
        }
        newnode->first = item;

        struct node* temp = s->lst;
        struct node* prv = NULL;
        for(int i = 0; i < pos; i++) {
            printf("skip %d\n", temp->first);
            prv = temp;
            temp = temp->rest;
        }
        newnode->rest = temp;
        if(pos == 0) {
            printf("insert as first\n");
            s->lst = newnode;
        } else {
            printf("insert before %d\n", temp->first);
            prv->rest = newnode;
        }

        ++s->length;
    }
}

并且add_to_front只需要一个语句

void add_to_front(Sequence s, int item) {
    sequence_insert_at(s, 0, item);
}

至于在列表的后面插入

void add_to_back(Sequence s, int item) {
    sequence_insert_at(s, s->length, item);
}

main函数的一个小测试

void print_sequence(Sequence s)
{
    struct node* temp = s->lst;
    for(int i = 0; i < s->length; temp = temp->rest) {
        printf("%d ", temp->first);
        i++;
    }
    printf("\n");
}

int main()
{
    Sequence derp = new_sequence();
    sequence_insert_at(derp, 0, 14);
    add_to_front(derp, 16);
    sequence_insert_at(derp, 0, 17);
    sequence_insert_at(derp, 2, 15);
    add_to_back(derp, 13);
    print_sequence(derp);
    delete_sequence(derp);
    return 0;
}

输出是:

17 16 15 14 13

您必须通过其他功能并修复它们。

最后我应该注意,如果没有误导,您选择的变量名称有点令人困惑,我会这样命名它们

typedef struct node {
  int data; /* the data that a node holds */
  struct node* next; /* the pointer to the next node */
} Node_t;

typedef struct sequence {
    struct node* head; /* head or first element of the sequence/list */
    int length; /* length is ok but size is better */
} Sequence_t;
于 2013-03-07T20:41:25.010 回答