今天是:
从今天开始,非特殊情况不会把写这些报告的时间记录在atimelogger中(因为写报告时时间的记录已经停止了),并且准备把明日的计划也贴在最后。
1.有所改动,貌似组内的大佬已经把所有工作承包了,而且报告日期推迟到了下周三,因此任务重心由“在4月12日之前准备好(推迟了)机器学习的最终报告——《畅想无监督学习》”变为了补充机器学习所需的数学知识(线性代数与概率统计)
2.完成专业课的作业(流体机械能转化、生物质能,新能源热利用可以往后稍稍);
3.备战蓝桥杯,为此:①1h左右的典型算法补充(优先Leetcode“探索”模块);②C/C++语法知识;③常见数据结构的构造与基本操作实现;④必要的练习与练题总结(比如时长1:30虚拟竞赛与“复盘”)
![]() |
![]() |
今天上午自己写了个cpp程序把二叉树实现了一下,为了写起来方便没把结构定义放在头文件中,途中遇到一个低级失误:在实现完先序遍历后,准备写中序和后序遍历函数时,忘记把函数体内的递归函数的名称改了,导致结果与预期不符,我找错误用了半个小时,真的心态有点小崩。教训就是:对于递归问题,Ctrl+C/V时一定要留意内部调用的函数是否需要变化。
以下是实现的cpp代码:
#include
#include
#include
using namespace std;
typedef int elem;
typedef struct TreeNode{
elem val;
struct TreeNode* left,*right;
}BiNode,*BiTree;
void visit(elem val){//访问操作
cout<<val<<endl;
}
void PreOrderTraverse(BiTree T){//先序遍历
if(T){
visit(T->val);
PreOrderTraverse(T->left);
PreOrderTraverse(T->right);
}
}
void PostOrderTraverse(BiTree T){//后序遍历
if(T){
//论复制粘贴的坏处,困扰了我半小时
//PreOrderTraverse(T->left);
//PreOrderTraverse(T->right);
PostOrderTraverse(T->left);
PostOrderTraverse(T->right);
visit(T->val);
}
}
void InOrderTraverse(BiTree T){//中序遍历
if(T){
//PreOrderTraverse(T->left);
InOrderTraverse(T->left);
visit(T->val);
//PreOrderTraverse(T->right);
InOrderTraverse(T->right);
}
}
//假定元素非负
void CreateBiTree(BiTree *T){//树的构建
int x;
cin>>x;
if(x<0) return;
else{
*T=(BiNode*)malloc(sizeof(BiNode));
(*T)->val=x;
(*T)->left=NULL;
(*T)->right=NULL;
CreateBiTree(&((*T)->left));//->的优先级比*高
CreateBiTree(&((*T)->right));
}
}
//静态数组(假定元素不超过6个)
void LOT(BiTree T){//按层次遍历
if(T){
int front=-1,rear=0;
BiTree queue[6];
BiTree p;
queue[0]=T;
while(front<rear){
p=queue[++front];
visit(p->val);
if(p->left)
queue[++rear]=p->left;
if(p->right)
queue[++rear]=p->right;
}
}
}
//STL模板
void LayerOrderTraverse(BiTree T){//按层次遍历
if(T){
queue<BiTree> q;
BiTree p;
q.push(T);
while(!q.empty()){
p=q.front();
q.pop();
visit(p->val);
if(p->left)
q.push(p->left);
if(p->right)
q.push(p->right);
}
}
}
int main(){
BiTree T;
CreateBiTree(&T);
cout<<"DLR"<<endl;
PreOrderTraverse(T);
cout<<"LRD"<<endl;
PostOrderTraverse(T);
cout<<"LDR"<<endl;
InOrderTraverse(T);
cout<<"LayerOrderTraverse:"<<endl;
//LayerOrderTraverse(T);
LOT(T);
free(T);
return 0;
}
目前Leetcode二叉树部分完成了2/3,还剩下总结篇的六道算法题。做这些题的目的便是熟悉竞赛时的风格,毕竟对于同一个知识点可能在形式上会有所变化。
先摆上在Leetcode上调试时遇到的几个问题:
以下是今日闯关的4道题,大多是用递归实现的,关于遍历(上午的代码已经展示过了)操作就不再列出了。部分题可以用迭代,但是暂时还不会。
Stage 01 二叉树的层序遍历
【题目描述】
这个应该令我印象最为深刻的一道题了,尽管层序遍历之前写过了,但就因为它的返回值形式使得这道题的写法大变样,要考虑层次以及容器的扩容。费了不少时间,以下是我的解法:
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
vector<vector<int>> v;
vector<vector<int>> levelOrder(TreeNode* root) {
if(root){
queue<pair<TreeNode*,int> >q;
TreeNode* node;
q.push(make_pair(root,0)); //
int cur_size=0; //v的当前数组元素个数
while(!q.empty()){
pair<TreeNode*,int>p=q.front();
node=p.first;
q.pop();
if(cur_size<=p.second){
cur_size=p.second+1;
v.resize(cur_size);
}
v[p.second].push_back(p.first->val);
if(node->left)
q.push(make_pair(node->left,p.second+1));
if(node->right)
q.push(make_pair(node->right,p.second+1));
}
}
return v;
}
};
Stage 02 二叉树的最大深度
【题目描述】
有自顶向下(top-down)以及自底向上(bottom-up)两种方法,选取方法的原则如下,我采用的是后者。
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
int ans=0;
int max(int a,int b){
return a>b?a:b;
}
int maxDepth(TreeNode* root) {
if(!root)
return 0;
return max(maxDepth(root->left),maxDepth(root->right))+1;
}
};
Stage 03 对称二叉树
【题目描述】
想了挺久的(主要是递归的方向选错了),不过看了别人的思路后很快就实现了。
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
bool isSymmetric(TreeNode* nl,TreeNode* nr){
if(!nl&&!nr)//两子树均为空
return true;
if(nl&&!nr||!nl&&nr)//一个为空,另一个不为空
return false;
if(nl->val!=nr->val)//判断两子树的节点是否相同
return false;
return isSymmetric(nl->left,nr->right)&
isSymmetric(nl->right,nr->left);
}
bool isSymmetric(TreeNode* root) {
if(!root)//空树被认为是对称的
return true;
return isSymmetric(root->left,root->right);
}
};
Stage 04 路径总和
【题目描述】
这个递归挺好想的,实现如下:
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
bool hasPathSum(TreeNode* root, int sum) {
if(!root)//空树返回false
return false;
if(!root->left&&!root->right)//叶子节点
return sum==root->val;
return hasPathSum(root->left,sum-root->val)|
hasPathSum(root->right,sum-root->val);
}
};
回想半年前,还在旁听数据结构的时候,当时是多么地抵触”树”,现在觉得好像也就那样(当然现在实现的操作都是些皮毛啦),这也是为何“早接触一些东西总会是好的”的缘故吧!