如何打印链接列表的斐波那契节点?例如,我们在链接列表中打印第一,第二,第三,第五,第八等节点

时间:2019-11-20 00:13:58

标签: c structure

我正在尝试找出最有效的方法。我下面有以下代码,用于打印前十个元素的斐波那契数列(使用记忆)

int main()
{
    int arrayWithFibIndices[100] = {0}; //Explanation for this array comes later
    int series[10] = {0}; //array to store the fibonacci values for last two iterations
    series[0] = 1; //hard coding the first two elements of the fib series
    series[1] = 2;
    for (int i = 0; i < 10; i++)
    {   
        if (series[i] != 0)
        {   
            printf ("series[%d]=%d.\n", i, series[i]);
        }   
        else 
        {   
            series[i] = series[i - 1] + series[i - 2]; 
            printf ("series[%d]=%d.\n", i, series[i]);
        }
        arrayWithFibIndices[series[i]] = 1;
    }   
}

我还有以下逻辑来迭代打印链表。

void printLL(struct node *temp)
{
    int i  = 0;
    while(temp != NULL)
    {   
        if (arrayWithFibIndices[i] != 0) //reason explained later below
        {
            printf("data:%d ", temp->data);
            temp = temp->next;
        }
        i++;
    }   
    printf("\n");
}

我正在尝试找出最有效的方法是什么?我想到的第一件事是创建一个新的数组arrayWithFibIndices []并将该数组的所有元素初始化为0。每当遇到斐波那契值时,我们就会在arrayWithFibIndices []中将该索引填充为1。稍后我们可以在打印链接列表的值之前,请检查arrayWithFibIndices []的每个索引。

我想到的第二个想法是创建一个队列。我将排队所有Fibonacci元素,当要打印链接列表时,我将在成功匹配时出队(匹配是队列元素与链接列表的第i个元素匹配。

你们还有其他建议吗?

2 个答案:

答案 0 :(得分:0)

您在描述中建议的解决方案将起作用。但是,您无需通过即可获得所有斐波那契数字的列表。您只需跟踪先前的编号,并使用它来偏移列表中的当前节点。

这是一个简单的示例,演示其工作方式。

#include <stdio.h>
#include <malloc.h>

struct node {
    int data;
    struct node *next;
};

void create_linked_list(struct node **root_ptr, int count) {
    struct node **curr_ptr = root_ptr;
    struct node *curr = NULL;
    for (int i = 0; i < count; i++) {
        *curr_ptr = (struct node *)malloc(sizeof(struct node *));
        curr = *curr_ptr;
        curr->data = i + 1;
        curr->next = NULL;
        curr_ptr = &(curr->next);
    }
}

void print_linked_list(struct node *root) {
    for(struct node *curr = root; curr != NULL; curr = curr->next) {
        printf("%d\n", curr->data);
    }
}

void print_linked_list_fib(struct node *root) {
    struct node *curr = root;

    // Print the root node twice because of 1,1
    // 1
    printf("%d\n", curr->data);
    int old_val = 1;

    // 1
    printf("%d\n", curr->data);
    int curr_val = 1;

    int offset = old_val;

    while (true) {
        // Keep moving until the next fibonacci node.
        for (int i = 0; i < offset; i++) {
            if (curr == NULL) return;
            curr = curr->next;
        }
        if (curr == NULL) return;
        printf("%d\n", curr->data);
        old_val = curr_val;
        curr_val = curr_val + offset;
        offset = old_val;
    }

}

int main() {
    struct node *root = NULL;
    const int count = 20;
    create_linked_list(&root, count);

    printf("\n\nList of all nodes\n");
    print_linked_list(root);

    printf("\n\nList of fibonacci nodes\n");
    print_linked_list_fib(root);
    return 0;
}

这是示例输出

List of all nodes
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20


List of fibonacci nodes
1
1
2
3
5
8
13

编辑:一种编写斐波那契节点打印功能的替代方法。 这样会将先前实现中的两个循环简化为一个循环。

void print_linked_list_fib_loop(struct node *root) {
    struct node *curr = root;

    // Print the root node twice because of 1,1
    // 1
    printf("%d\n", curr->data);
    int old_val = 1;

    // 1
    printf("%d\n", curr->data);
    int curr_val = 1;

    int i = 0;
    curr = curr->next;
    for(struct node *curr = root; curr != NULL; curr = curr->next) {
        if (i == old_val) {
            old_val = curr_val;
            curr_val = curr_val + i;
            i = 0;
            printf("%d\n", curr->data);
        }
        i++;
    }
}

答案 1 :(得分:0)

如果您还在设计和构建列表,则在构建过程中,可以将斐波那契节点的地址复制到struct node*的单独数组中。为了管理节点的任何重新排序,您可以将列表位置存储在每个节点中(并在例如添加或删除节点时更改列表位置)。如果列表会经常被处理,这会产生开销,但是打印斐波那契节点非常有效:只需遍历指针数组,而无需遍历链接列表。