Ordered Fractions(二叉搜索树)

题意:输入一个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;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值