DS:二叉树递归&朋友圈计算

一个小时写完上机作业~敲开心!!
最近的数据结构在讲Hash函数和图,发现2019年要结束这门课的期末,简直爽呆…
无论怎样,都要加油呀!!冲冲冲😃

来康康今天的上机题

二叉查找树中的最小绝对差

有一棵结点值全为非负数的二叉查找树,设计程序输出该树中结点值的最小绝对差。a和b的最小绝对差为|a – b|。要求输入二叉查找树的层次遍历,并使用二叉链表的方式保存二叉查找树
例如
1
  \
   3
   / \
  2 5

输入:二叉查找树的层次遍历序列,“1 -1 3 -1 -1 2 5”,可以从 input_12_1.txt”读取输入 ,可以从控制台依次输出也可以选择从文本当中读取输入

输出:该树结点的最小绝对差,1(3-2=1),输出结果写入 output_12_1.txt;也可以直接将最终结果打印到控制台

#include <iostream>
#include <math.h>
using namespace std;
int n,a[100],minnum=999;
template <typename T>
class BinTreeNode
{
public:
    BinTreeNode(){lchild=NULL;rchild=NULL;}
    T data;
    BinTreeNode *lchild, *rchild;
    BinTreeNode(const T&t):data(t),lchild(NULL),rchild(NULL){}
};

template <typename T>
class BinTree
{
public:
    BinTree(){root=new BinTreeNode<T>;root->lchild=NULL;root->rchild=NULL;}
    BinTreeNode<T> *root;
    void create(BinTreeNode<T> *root,int i);
    void show(BinTreeNode<T> *root);
    void findmin(BinTreeNode <T> *root,BinTreeNode<T> *begin);
};

template<typename T>
void BinTree<T>::create(BinTreeNode<T> *root,int i)
{  if(i>=n) return;
root->data=a[i];
if(2*i+1<n){
    root->lchild=new BinTreeNode<T>;
    root->lchild->lchild=NULL;
    create(root->lchild,2*i+1);}
if(2*i+2<n){
    root->rchild=new BinTreeNode<T>;
    root->rchild->lchild=NULL;
    root->rchild->rchild=NULL;
    create(root->rchild,2*i+2);}
}

template<typename T>
void BinTree<T>::show(BinTreeNode<T> *root)
{  if(root==NULL) return;
    else cout<<root->data<<" ";
    show(root->lchild);
    show(root->rchild);
}

template<typename T>
void BinTree<T>::findmin(BinTreeNode<T> *root,BinTreeNode<T> *begin)
{   if(root==NULL||begin==NULL||root->data==-1||begin->data==-1) return;
    if(begin->lchild==NULL&&begin->rchild==NULL) return;
    int temp,temp1=999,temp2=999;
    if(begin->lchild==NULL||begin->lchild->data==-1) ;
    else temp1=abs((root->data)-(begin->lchild->data));
    if(begin->rchild==NULL||begin->rchild->data==-1) ;
    else temp2=abs((root->data)-(begin->rchild->data));
    temp=temp1>=temp2?temp2:temp1;
    if(temp<minnum) minnum=temp;
    if(temp1>=temp2)findmin(root,begin->rchild);
    if(temp1<temp2)findmin(root,begin->lchild);
    findmin(root->lchild,root->lchild);
    findmin(root->rchild,root->rchild);
}
int main()
{
    BinTree<int> tree;
    cout<<"input n:"<<endl;
    cin>>n;
    cout<<"input "<<n<<" numbers:(if NULL please input -1)"<<endl;
    for(int i=0;i<n;i++)
        cin>>a[i];
    tree.create(tree.root,0);
    cout<<"tree:"<<endl;
    tree.show(tree.root);cout<<endl;
    tree.findmin(tree.root,tree.root);
    cout<<"result:"<<endl;
    cout<<minnum<<endl;
}

思路:递归,有两个参数,一个是当前的操作数,另一个是开始比较的结点,操作数与左孩子的绝对差为temp1,与右孩子的绝对差为temp2,选取较小者保存,若小于最小值,保存其为最小值。如果temp1较小,则开始比较的结点改为lchild,(因为可能存在左孩子结点的左孩子结点与操作数的绝对差更小的情况),否则改为rchild。在当前操作数全部比完后,依次改为下一个结点比较。
感觉思路棒棒哒!!就是写的时候有个BUG调了很久:
Thread 1: Exc_BAD_ACCESS(code=2, address=xxx-xxxx)
出现这种code=2的错误就证明有无限次调用啦!!要记住
(其实是粗心写错了……😭)

参考:http://www.itkeyword.com/doc/7677676443698290x634/thread-1-exc-bad-accesscode-2-address-xxx-xxxx

班级中朋友圈的数目

一个班级有N个学生。这些学生中有些是朋友,有些则不是。班级学生的友谊具有转移的特点。例如,假如A是B的直接朋友,同时B是C的直接朋友,那么A是C的间接朋友。这样,“朋友圈”可定义为直接和间接朋友的一个集合

给定一个N*N的矩阵M来表示一个班级的朋友关系。如果M[i][j]=1,则说明第i个学生和第j个学生互为直接朋友,否则他们不具有朋友关系。例如,有朋友关系矩阵[[1,1,0],[1,1,0],[0,0,1]],则该班级的朋友圈个数为2,因为学生0和学生1是直接朋友,他们在一个朋友圈内,而学生2自己在一个朋友圈内。又如,对于朋友关系矩阵[[1,1,0],[1,1,1],[0,1,1]],则该班级的朋友圈个数为1,因为学生0和学生1是直接朋友,学生1和学生2是直接朋友,学生0和学生2是间接朋友,这三个学生处于同一个朋友圈

输入
朋友关系矩阵

输出
输出对应班级的朋友圈个数

注意
(1)N 的范围是[1,200]
(2)对所有学生,M[i][i] = 1
(3)如果M[i][j] = 1,则M[j][i] = 1

#include <iostream>
using namespace std;
int matrix[200][200],n=0;

int main()
{   int num=1;
    while(1){
    cout<<"input n:"<<endl;
    cin>>n;
        if(n<0||n>200) cout<<"error:"<<endl;
        else break;
    }
    cout<<"input matrix:"<<endl;
    for(int i=0;i<n;i++)
        for(int j=0;j<n;j++)
            cin>>matrix[i][j];
    for(int i=1;i<n;i++)
    {int flag=0;
        for(int j=0;j<i;j++)
            if(matrix[i][j]!=0) flag=1;
        if(!flag) num++;}
    cout<<"result:"<<endl;
    cout<<num<<endl;
    }

这么短的代码…真实感动
思路:灵机一动!!
提示里也说了,这一定是个对称矩阵,且对角线都为1,发现对角线上/下方的数据可以利用。如果一列对角线上方的数字都为0,则可以认为它是独立的一个朋友圈。(似乎是利用了对称矩阵的性质!!)

期末季了,一个个ddl在轰炸
最近也遇到了不少烦恼,感觉自己做的不错却没有得到肯定,好不容易努力的事情却不被当回事情,这些都会有点挫败的感觉
但是依旧有一起努力的队友,甘愿为了最终的pre效果一起承担,一起熬夜,感觉和他们一起努力,我一定不能掉队啊
期末冲冲冲!!愿一切都是想要的结局

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值