Ordered Fractions(二叉搜索树)

来源:互联网 发布:手机电脑连接软件 编辑:程序博客网 时间:2024/04/30 16:26

题意:输入一个n,按从小到大的顺序输出从0到1之间的所有分母不大于n的最简分数。

比较容易想到的是排序。可以用结构体表示一个分数,将所有符合条件的分数都存到数组里,然后sort一下,输出就行。注意cmp函数的写法


bool cmp(node x,node y){return x.a*y.b<x.b*y.a;  //比较两个分数的大小,交叉相乘}

 最近刚学了二叉树,可以用二叉查找树,实现插入排序。

0/1和1/1这两个值只能逼近不能达到,直接输出即可。

根据二叉查找树的性质,显然1/2是该树的head。

然后分子分母从小到大,往树里进行插入。如果发现树中已有相同的值,说明该分数不是最简,而且已经有最简的在树里了,直接pass掉这个分数即可。

最后,中序遍历输出即可。


#include <cstdio>#include <cstring>using namespace std;struct Node{    int up;    int down;    Node *left;    Node *right;    Node *p;    Node()    {        left=NULL;        right=NULL;        p=NULL;    }}*head;void Insert(Node* t){    Node *th;    th=head;    Node* y;    y=NULL;    while(th!=NULL)    {        y=th;        if(t->up*th->down>t->down*th->up)        {                th=th->right;        }        else if(t->up*th->down==t->down*th->up)        {            return; //相同元素,说明不是最简分数,并且前面肯定出现过了。        }        else th=th->left;    }    t->p=y; //让t的p指针指向y    if(y==NULL)//如果树为空。本题不用考虑。    {        head=t;    }    else if(t->up*y->down > t->down*y->up) //把待插结点,插在y的下面(让y指向t)。    {        y->right=t;    }    else y->left=t;}void inorder(Node* head){    Node* th;    th=head;    if(th!=NULL)    {        inorder(th->left);        printf("%d/%d\n",th->up,th->down);        inorder(th->right);    }}int main(){    int n;    while(scanf("%d",&n)!=EOF)    {        printf("0/1\n");        if(n==1)        {            printf("1/1\n\n");            continue;        }        head=new Node();        head->up=1;        head->down=2;        for(int i=2; i<=n; i++)        {            for(int j=1; j<i; j++)            {                Node *t;                t=new Node();                t->up=j;                t->down=i;                Insert(t);            }        }        inorder(head);        printf("1/1\n\n");    }    return 0;}