k阶斐波那契数列:
数列第1项到第k-1项为0,第k项和第k+1项为1,从第k+2项开始每一项都是前k项的和
要注意!!!!不是前两项的和,而是前k项的和。(我因为这个卡了好久...)
| 斐波那契数列的每一项(n≥3)是前两项的和
| k阶斐波那契数列的每一项(n≥k + 2)是前k项的和
错误结果:
正确结果:
k = 2时 数列:0, 1, 1, 2, 3, 5, 8, 13, 21......
k = 3 时 数列:0, 0, 1, 1, 2, 4, 7, 13, 24, 44......
k = 4 时 数列:0, 0, 0, 1, 1, 2, 4, 8, 15, 39.......
题解:
题目说要使用大小为k个存储空间的循环队列,所以我首先建立一个循环队列
我的想法是:先构建大小为k的链表,最后让队尾连接队头就行了
// 循环队列结构体定义
typedef struct node {
int num; // 数据
struct node* next; // 指针
}node;
typedef struct queue
{
int len; // 队列长度:赋值为k
struct node* front; // 队头指针
struct node* rear; // 队尾指针
}queue;
// --- 创建一个大小为k的循环队列 ---
void CreateQueue(queue* Q,int len) //创建一个循环队列
{
Q->len = len; //队列容量
node* p1 = (node*)malloc(sizeof(node)); // 先给队列一个结点
if (!p1) return;
Q->front = Q->rear = p1; // 容量为1的队列 队头队尾指向同一个结点
while (--len) { // 这个while循环会给队列加入 len - 1 的结点
node *newnode = (node*)malloc(sizeof(node));
if(!newnode) printf("Allocation error");
Q->rear->next = newnode;
Q->rear = newnode;
}
Q->rear->next = Q->front; // 最后让队尾连接队头,构成循环队列
计算k阶斐波那契数列的每一项:
// --- k(k>=2)阶斐波那契数列计算 ---
// 前k-1项返回0,k和k+1项返回1,第n(n>=k+2)项返回前k项和
// 经过推导第n项是 (第n-1项*2 + 第n-k-1项)---- 即kfb(n) = kfb(n-1) * 2 + kfb(n-k-1)
// 附上代码:
int kfb(int n, int k) // 第n项,k阶
{
if (n < k) return 0;
else if (n == k || n == k + 1) return 1;
else return (kfb(n - 1, k) * 2 - kfb(n - k - 1, k));
}
接下来将每一项的值赋给循环队列:
void Fibonacci(queue* Q, int max)
{
node* p = Q->front;
int k = Q->len;
int n = 1; // 从第1项开始
while (1) {
int t = kfb(n, k); // 得到第n项的值
if (t > max)break;
p->num = t;
p = p->next;
if (n > k) { // 当n = k -1时,队列已满,因此n > k时需要向后移动队首队尾指针
Q->front = Q->front->next;
Q->rear = Q->rear->next;
}
n++;
}
}
贴上源码:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
/* 第十题:k阶斐波那契数列 */
typedef struct node {
int num;
struct node* next;
}node;
typedef struct queue
{
int len;
struct node* front;
struct node* rear;
}queue;
void CreateQueue(queue* Q,int len) //创建一个循环队列
{
Q->len = len; //队列容量
node* p1 = (node*)malloc(sizeof(node));
if (!p1) return;
Q->front = Q->rear = p1;
while (--len) {
node *newnode = (node*)malloc(sizeof(node));
if(!newnode) printf("Allocation error");
Q->rear->next = newnode;
Q->rear = newnode;
}
Q->rear->next = Q->front;
}
int kfb(int n, int k)
{
if (n < k) return 0;
else if (n == k || n == k + 1) return 1;
else return (kfb(n - 1, k) * 2 - kfb(n - k - 1, k));
}
int fb(int n)
{
if (n < 2) return 1;
else return fb(n - 1) + fb(n - 2);
}
void Fibonacci(queue* Q, int max)
{
node* p = Q->front;
int k = Q->len;
int n = 1;
while (1) {
int t = kfb(n, k);
if (t > max)break;
p->num = t;
p = p->next;
if (n > k) {
Q->front = Q->front->next;
Q->rear = Q->rear->next;
}
n++;
}
}
void output(node* p,int n)
{
for (int i = 0; i < n; i++)
{
printf("%d ", p->num);
p = p->next;
}
}
int main()
{
queue* q;
if(!(q = (queue*)malloc(sizeof(queue)))) return 0;
int max;
scanf("%d", &max);
int k = 0;
scanf("%d", &k);
CreateQueue(q, k);
Fibonacci(q, max);
output(q->front, q->len);
return 0;
}
C