二叉查找树、平衡二叉树

        树结构练习——排序二叉树的中序遍历

Time Limit: 1000MS Memory Limit: 65536KB
Problem Description
在树结构中,有一种特殊的二叉树叫做排序二叉树,直观的理解就是——(1).每个节点中包含有一个关键值 (2).任意一个节点的左子树(如果存在的话)的关键值小于该节点的关键值 (3).任意一个节点的右子树(如果存在的话)的关键值大于该节点的关键值。现给定一组数据,请你对这组数据按给定顺序建立一棵排序二叉树,并输出其中序遍历的结果。

Input
输入包含多组数据,每组数据格式如下。
第一行包含一个整数n,为关键值的个数,关键值用整数表示。(n<=1000)
第二行包含n个整数,保证每个整数在int范围之内。
Output
为给定的数据建立排序二叉树,并输出其中序遍历结果,每个输出占一行。

Example Input

1
2
2
1 20

Example Output

2
1 20

Hint

Author
赵利强
代码实现:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct node
{
  int data;
  struct node * left, *right;
};
int ans[3000], top;
struct node * creat(struct node * root, int k)
{
   if(root==NULL)
   {
      root = (struct node *)malloc(sizeof(struct node));
      root->data = k;
      root->left = NULL;
      root->right = NULL;
      return root;
   }
   if(root->data>k)
   {//k<root->data,所以向左走
   root->left = creat(root->left, k);
   }
   else
   root->right = creat(root->right, k);//否则,向右走
   return root;
}
void mid(struct node* root)//中序遍历
{
   if(root)
   {
     mid(root->left);
     ans[top++] = root->data;//放入队列
     mid(root->right);
   }
}
int main()
{
   int n,m, i;
   while(~scanf("%d", &n))
   {
     struct node * root;
     root = (struct node *)malloc(sizeof(struct node));
     root = NULL;
     for(i=0;i<n;i++)
     {
       scanf("%d", &m);
       root = creat(root, m);
     }
     top = 0;//注意(在这错过好多次,忘记把top改为0了)
     mid(root);
     for(i=0;i<top-1;i++)
     printf("%d ", ans[i]);
     printf("%d\n", ans[i]);
   }
    return 0;
}

例题2:
迷失の搜索树
Time Limit: 1000MS Memory Limit: 65536KB
Problem Description

小璐在机缘巧合之下获得了一个二叉搜索树,这个二叉搜索树恰好有n个节点,每个节点有一个权值,每个节点的权值都在[1,n]这个区间内,并且两两不相同,真是优美的性质啊

但是命运的不公又让她失去了这个二叉搜索树

幸运的是,她还记得自己丢失的二叉搜索树的前序遍历序列。

在丢了二叉搜索树之后,小璐无比想念她的这个树的后序遍历

那么问题来了,聪明的你在知道这个二叉搜索树的前序遍历的序列的情况下,能帮她找到这个二叉搜索树的后序遍历嘛?
Input

多组输入,以文件结尾

每组数据第一行为一个整数n,代表这个二叉搜索树的节点个数(1<=n<=100)

接下来一行n个整数,代表这个二叉搜索树的前序遍历序列
Output

输出n个整数

表示这个二叉树的后序遍历序列
Example Input

5
4 2 1 3 5

Example Output

1 3 2 5 4

Hint

二叉查找树是一棵空树,或者是具有下列性质的二叉树:

若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值

若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值

它的左、右子树也分别为二叉排序树
Author
2016暑假集训结训赛 by QAQ
代码实现:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct node
{
  int data;
  struct node * left, *right;
};
struct node * creat(struct node * root, int a)
{
   if(root==NULL)
   {
      root = (struct node *)malloc(sizeof(struct node));
      root->data = a;
      root->left = NULL;
      root->right = NULL;
      return root;
   }
   if(root->data>a)
   {
   root->left = creat(root->left, a);
   }
   else
   root->right = creat(root->right, a);
   return root;
}
int ans[150], top, a[150];
void qian(struct node * root)//前序遍历
{
   if(root)
   {
      qian(root->left);
      qian(root->right);
      ans[top++] = root->data;
   }
}
int main()
{
    int n, i;
    while(~scanf("%d", &n))
    {
    struct node * root;
    root = (struct node*)malloc(sizeof(struct node));
    for(int i=0;i<n;i++)
    {
    scanf("%d", &a[i]);
    root = creat(root, a[i]);
    }
    top = 0;
    qian(root);
    for(i=0;i<n-1;i++)
    printf("%d ", ans[i]);
    printf("%d\n", ans[i]);
    }
    return 0;
}

今天的大菜!!!
例题3:
数据结构实验之查找二:平衡二叉树
Time Limit: 400MS Memory Limit: 65536KB
Problem Description

根据给定的输入序列建立一棵平衡二叉树,求出建立的平衡二叉树的树根。
Input

输入一组测试数据。数据的第1行给出一个正整数N(n <= 20),N表示输入序列的元素个数;第2行给出N个正整数,按数据给定顺序建立平衡二叉树。
Output

输出平衡二叉树的树根。
Example Input

5
88 70 61 96 120

Example Output

70

Hint

Author
xam
代码实现:
(C++)

#include<iostream>
#include<stdio.h>
using namespace std;
typedef struct node
{
    int data,deep;
    struct node *l,*r;
}st;
int height(st *root)
{
    if(root==NULL)
        return -1;
    return root->deep;
}
st *LLchange(st *root)
{
    st *p;
    p=root->l;
    root->l=p->r;
    p->r=root;
    p->deep=max(height(p->l),height(p->r))+1;
    root->deep=max(height(root->l),height(root->r))+1;
    return p;
}
st *RRchange(st *root)
{
    st *p;
    p=root->r;
    root->r=p->l;
    p->l=root;
    p->deep=max(height(p->l),height(p->r))+1;
    root->deep=max(height(root->l),height(root->r))+1;
    return p;
}
st *LRchange(st *root)
{
    root->l=RRchange(root->l);
    return LLchange(root);
}
st *RLchange(st *root)
{
    root->r=LLchange(root->r);
    return RRchange(root);
}
st *Push(st *root,int k)
{
    if(root==NULL)
    {
        root=new st;
        root->data=k;
        root->deep=0;
        root->l=root->r=NULL;
    }
    else if(k<root->data)
    {
        root->l=Push(root->l,k);
        if(height(root->l)-height(root->r)==2)
        {
            if(k<root->l->data)
                root=LLchange(root);
            else
                root=LRchange(root);
        }
    }
    else if(k>root->data)
    {
        root->r=Push(root->r,k);
        if(height(root->r)-height(root->l)==2)
        {
            if(k<root->r->data)
                root=RLchange(root);
            else
                root=RRchange(root);
        }
    }
    root->deep=max(height(root->l),height(root->r))+1;
    return root;
}
int main()
{
    int n,k;
    while(~scanf("%d", &n))
    {
        st *root=NULL;
        while(n--)
        {
            scanf("%d", &k);
            root=Push(root,k);
        }
        printf("%d\n",root->data);
    }
    return 0;
}

代码实现:
(C)

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
struct node
{
    int data;
    int deep;
    struct node *left;
    struct node *right;
};
int max(int a, int b)
{
  if(a>=b)
  return a;
  else
  return b;
}
int height(struct node *root)
{
    if(root==NULL)
        return -1;
    return root->deep;
}
struct node *LLchange(struct node *root)
{
    struct node *p;
    p=root->left;
    root->left=p->right;
    p->right=root;
    p->deep=max(height(p->left),height(p->right))+1;
    root->deep=max(height(root->left),height(root->right))+1;
    return p;
}
struct node *RRchange(struct node *root)
{
    struct node *p;
    p=root->right;
    root->right=p->left;
    p->left=root;
    p->deep=max(height(p->left),height(p->right))+1;
    root->deep=max(height(root->left),height(root->right))+1;
    return p;
}
struct node *LRchange(struct node*root)
{
    root->left=RRchange(root->left);
    return LLchange(root);
}
struct node *RLchange(struct node *root)
{
    root->right=LLchange(root->right);
    return RRchange(root);
}
struct node *Push(struct node *root,int k)
{
    if(root==NULL)
    {
        root=(struct node *)malloc(sizeof(struct node));
        root->data=k;
        root->deep=0;
        root->left=root->right=NULL;
    }
    else if(k<root->data)
    {
        root->left=Push(root->left,k);
        if(height(root->left)-height(root->right)==2)
        {
            if(k<root->left->data)
                root=LLchange(root);
            else
                root=LRchange(root);
        }
    }
    else if(k>root->data)
    {
        root->right=Push(root->right,k);
        if(height(root->right)-height(root->left)==2)
        {
            if(k<root->right->data)
                root=RLchange(root);
            else
                root=RRchange(root);
        }
    }
    root->deep=max(height(root->left),height(root->right))+1;
    return root;
}
int main()
{
    int n,k;
    while(~scanf("%d", &n))
    {
        struct node *root=NULL;
        while(n--)
        {
            scanf("%d", &k);
            root=Push(root,k);
        }
        printf("%d\n",root->data);
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值