我正在尝试找出最有效的方法。我下面有以下代码,用于打印前十个元素的斐波那契数列(使用记忆)
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个元素匹配。
你们还有其他建议吗?
答案 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*
的单独数组中。为了管理节点的任何重新排序,您可以将列表位置存储在每个节点中(并在例如添加或删除节点时更改列表位置)。如果列表会经常被处理,这会产生开销,但是打印斐波那契节点非常有效:只需遍历指针数组,而无需遍历链接列表。