此题利用层次遍历和队列的联系,完全二叉树的性质,来实现代码
即输入m,将此数入队列,
处理队顶元素,其儿子结点的值是其二倍和二倍加一,出队列,将其儿子结点入队列,
重复此过程,直到某结点的儿子结点超出总的结点数目(n),此时进入过队列的元素个数即为子树结点个数。
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
typedef struct QNode
{
int data;
struct QNode* next;
}QNode, * QueuePtr;
void EnQueue(QueuePtr* rear, int e);
int DeQueue(QueuePtr* front, QueuePtr* rear);
int main()
{
QueuePtr front = (QueuePtr)malloc(sizeof(QNode));
QueuePtr rear = front;
int m, n;
int i, j = 0;
int sum;
while (1)
{
scanf("%d %d", &m, &n);
if (m == 0 && n == 0)
break;
EnQueue(&rear, m);
sum = 1;
while (1)
{
int flag = 0;
if ((front->next->data) * 2 <= n)
{
EnQueue(&rear, front->next->data * 2);
sum++;
flag = 1;
}
if ((front->next->data) * 2 + 1 <= n)
{
EnQueue(&rear, front->next->data * 2 + 1);
sum++;
flag = 1;
}
DeQueue(&front, &rear);
if (flag == 0)
break;
}
while (front != rear)//把队列清空
DeQueue(&front, &rear);
j++;
printf("%d\n", sum);
}
return 0;
}
void EnQueue(QueuePtr* rear, int e)
{
QueuePtr q = (QueuePtr)malloc(sizeof(QNode));
q->data = e;
q->next = NULL;
(*rear)->next = q;
*rear = q;
}
int DeQueue(QueuePtr* front, QueuePtr* rear)
{
QueuePtr q = (*front)->next;
int e = q->data;
(*front)->next = (*front)->next->next;
if (*rear == q)
*rear = *front;
free(q);
return e;
}
ps:每次输入一个情况就可以立刻输出结果,不用把所有结果最后一起输出,当然也可以这么做(oj也可以通过),但没有必要。(本人一开始没明白,将所有结果都存起来,一起输出了,哎)