递归怎么写:
-
确定递归函数的参数和返回值: 确定哪些参数是递归的过程中需要处理的,那么就在递归函数里加上这个参数, 并且还要明确每次递归的返回值是什么进而确定递归函数的返回类型。
-
确定终止条件: 写完了递归算法, 运行的时候,经常会遇到栈溢出的错误,就是没写终止条件或者终止条件写的不对,操作系统也是用一个栈的结构来保存每一层递归的信息,如果递归没有终止,操作系统的内存栈必然就会溢出。
-
确定单层递归的逻辑: 确定每一层递归需要处理的信息。在这里也就会重复调用自己来实现递归的过程。
前序:
*returnsize:
记录ans的大小!ans[(*returnsize)++]=???
void f(struct TreeNode*t,int *ans,int *returnSize){
if(t==NULL) return;
ans[(*returnSize)++]=t->val;
f(t->left,ans,returnSize);
f(t->right,ans,returnSize);
}
int* preorderTraversal(struct TreeNode* root, int* returnSize) {
int *ans=(int *)malloc(sizeof(int)*100);
*returnSize=0;
f(root,ans,returnSize);
return ans;
}
中序
void f(struct TreeNode* r,int *ans,int *returnSize){
if(r==NULL) return;
f(r->left,ans,returnSize);
ans[(*returnSize)++]=r->val;
f(r->right,ans,returnSize);
}
int* inorderTraversal(struct TreeNode* root, int* returnSize) {
int *ans=(int *)malloc(sizeof(int)*100);
*returnSize=0;
f(root,ans,returnSize);
return ans;
}
后序
void f(struct TreeNode* r,int *ans,int *returnSize){
if(r==NULL) return;
f(r->left,ans,returnSize);
f(r->right,ans,returnSize);
ans[(*returnSize)++]=r->val;
}
int* postorderTraversal(struct TreeNode* root, int* returnSize) {
int *ans=(int *)malloc(sizeof(int)*100);
*returnSize=0;
f(root,ans,returnSize);
return ans;
}
层序遍历
算法:
用队列 : struct TreeNode**queue
重点在于怎么区分这一层还是下一层,输出一层后记录rear-front,输出元素个数<=rear-front则在本层,大于则进入了下一层(重新记录rear-front,输出元素个数归0)
注意**:
int**:
相当于二阶数组,存放int类型
int** ans=(int*)malloc(sizeof(int*) * ??);定义第一维
ans[??] =(int *)malloc(sizeof(int) *???); 定义第二维
leetcode答题相关:
*returnsize:指向一个int,第一维中 在第几层,最后返回总共有几层
**returnColunmSizes:指向*returnColunmSizes这个一维数组,表示第i层有几个元素
(*returnColumnSizes)[*returnSize]=j;
int** levelOrder(struct TreeNode* root, int* returnSize, int** returnColumnSizes) {
int **ans=(int **)malloc(sizeof(int *)*2001);//最后返回的答案
*returnColumnSizes = (int*)malloc(sizeof(int) * 2001);//每层有几个元素,有几层
*returnSize=0;//第几层
if(root==NULL) return NULL;
struct TreeNode**queue=(struct TreeNode**)malloc(sizeof(struct TreeNode*)*5000);//队列
int front=-1,rear=-1;//先放入第一个元素
queue[++rear]=root;
while(front!=rear){//非空
int howmany=rear-front;//说明这一层有几个元素
int j=0;
ans[*returnSize]=(int *)malloc(sizeof(int)*howmany);
while(j<howmany){
struct TreeNode* pop_tree=queue[++front];//反映层数
ans[*returnSize][j++]=pop_tree->val;
if(pop_tree->left) queue[++rear]=pop_tree->left;
if(pop_tree->right) queue[++rear]=pop_tree->right;
}
(*returnColumnSizes)[*returnSize]=j;
(*returnSize)++;
}
return ans;
}
从下到上层序遍历
在上一题的基础上反向输出即可!
**returnsize也要随之更改
int** levelOrderBottom(struct TreeNode* root, int* returnSize, int** returnColumnSizes) {
int **ans=(int **)malloc(sizeof(int *)*2001);//最后返回的答案
*returnColumnSizes = (int*)malloc(sizeof(int) * 2001);//每层有几个元素,有几层
*returnSize=0;//第几层
if(root==NULL) return NULL;
struct TreeNode**queue=(struct TreeNode**)malloc(sizeof(struct TreeNode*)*5000);//队列
int front=-1,rear=-1;//先放入第一个元素
queue[++rear]=root;
while(front!=rear){//非空
int howmany=rear-front;//说明这一层有几个元素
int j=0;
ans[*returnSize]=(int *)malloc(sizeof(int)*howmany);
while(j<howmany){
struct TreeNode* pop_tree=queue[++front];//反映层数
ans[*returnSize][j++]=pop_tree->val;
if(pop_tree->left) queue[++rear]=pop_tree->left;
if(pop_tree->right) queue[++rear]=pop_tree->right;
}
(*returnColumnSizes)[*returnSize]=j;
(*returnSize)++;
}
int i=0;
int j=*returnSize-1;
while(i<j){
int*tem=ans[i];
ans[i]=ans[j];
ans[j]=tem;
int cur=(*returnColumnSizes)[i];
(*returnColumnSizes)[i]=(*returnColumnSizes)[j];
(* returnColumnSizes)[j]=cur;
i++;
j--;
}
return ans;
}
二叉树的右视图
在输出每一行元素那边进行修改!
int* rightSideView(struct TreeNode* root, int* returnSize) {
int *ans=(int *)malloc(sizeof(int)*101);//最后返回的答案
*returnSize=0;//第几层
if(root==NULL) return NULL;
struct TreeNode**queue=(struct TreeNode**)malloc(sizeof(struct TreeNode*)*1000);//队列
int front=-1,rear=-1;//先放入第一个元素
queue[++rear]=root;
while(front!=rear){//非空
int howmany=rear-front;//说明这一层有几个元素
int j=0;
while(j<howmany){
struct TreeNode* pop_tree=queue[++front];//反映层数
if(j==howmany-1) ans[*returnSize]=pop_tree->val;//这一步保证输出的都是每一行最后一个元素
j++;
if(pop_tree->left) queue[++rear]=pop_tree->left;
if(pop_tree->right) queue[++rear]=pop_tree->right;
}
(*returnSize)++;
}
return ans;
}
637.二叉树的层平均值
double* averageOfLevels(struct TreeNode* root, int* returnSize) {
double* ans=(double*)malloc(sizeof(double)*10001);
*returnSize=0;
struct TreeNode*queue[10001];
int front=-1;
int rear=-1;
queue[++rear]=root;
while(front!=rear){
int howmany=rear-front;
int j=0;
double sum=0;
while(j<howmany){
struct TreeNode *pop_tree=queue[++front];
sum+=pop_tree->val;
if(pop_tree->left) queue[++rear]=pop_tree->left;
if(pop_tree->right) queue[++rear]=pop_tree->right;
j++;
}
ans[(*returnSize)++]=sum/j;
}
return ans;
}
429.N叉树的层序遍历
加入孩子的方式发生了变化
int** levelOrder(struct Node* root, int* returnSize, int** returnColumnSizes) {
int **ans=(int **)malloc(sizeof(int *)*20000);//最后返回的答案
*returnColumnSizes = (int*)malloc(sizeof(int) * 20000);//每层有几个元素,有几层
*returnSize=0;//第几层
if(root==NULL) return NULL;
struct Node**queue=(struct Node**)malloc(sizeof(struct Node*)*50000);//队列
int front=-1,rear=-1;//先放入第一个元素
queue[++rear]=root;
while(front!=rear){//非空
int howmany=rear-front;//说明这一层有几个元素
int j=0;
ans[*returnSize]=(int *)malloc(sizeof(int)*howmany);
while(j<howmany){
struct Node* pop_tree=queue[++front];//反映层数
ans[*returnSize][j++]=pop_tree->val;
for(int i=0;i<pop_tree->numChildren;i++){
queue[++rear]=pop_tree->children[i];//加入孩子的方式发生了变化
}
}
(*returnColumnSizes)[*returnSize]=j;
(*returnSize)++;
}
free(queue);
return ans;
}
515.在每个树行中找最大值
int** levelOrderBottom(struct TreeNode* root, int* returnSize, int** returnColumnSizes) {
int **ans=(int **)malloc(sizeof(int *)*2001);//最后返回的答案
*returnColumnSizes = (int*)malloc(sizeof(int) * 2001);//每层有几个元素,有几层
*returnSize=0;//第几层
if(root==NULL) return NULL;
struct TreeNode**queue=(struct TreeNode**)malloc(sizeof(struct TreeNode*)*5000);//队列
int front=-1,rear=-1;//先放入第一个元素
queue[++rear]=root;
while(front!=rear){//非空
int howmany=rear-front;//说明这一层有几个元素
int j=0;
ans[*returnSize]=(int *)malloc(sizeof(int)*howmany);
while(j<howmany){
struct TreeNode* pop_tree=queue[++front];//反映层数
ans[*returnSize][j++]=pop_tree->val;
if(pop_tree->left) queue[++rear]=pop_tree->left;
if(pop_tree->right) queue[++rear]=pop_tree->right;
}
(*returnColumnSizes)[*returnSize]=j;
(*returnSize)++;
}
int i=0;
int j=*returnSize-1;
while(i<j){
int*tem=ans[i];
ans[i]=ans[j];
ans[j]=tem;
int cur=(*returnColumnSizes)[i];
(*returnColumnSizes)[i]=(*returnColumnSizes)[j];
(* returnColumnSizes)[j]=cur;
i++;
j--;
}
return ans;
}
#116.填充每个节点的下一个右侧节点指针
struct Node* connect(struct Node* root) {
if(root==NULL) return NULL;
struct Node**queue=(struct Node**)malloc(sizeof(struct Node*)*60000);//队列
int front=-1,rear=-1;//先放入第一个元素
queue[++rear]=root;
while(front!=rear){//非空
int howmany=rear-front;//说明这一层有几个元素
int j=0;
struct Node* prior=NULL;
while(j<howmany){
struct Node* pop_tree=queue[++front];//反映层数
if(prior!=NULL) {
prior->next=pop_tree;
}
prior=pop_tree;
pop_tree->next=NULL;
if(pop_tree->left) queue[++rear]=pop_tree->left;
if(pop_tree->right) queue[++rear]=pop_tree->right;
j++;
}
}
return root;
}
104.二叉树的最大深度&&111.二叉树的最小深度
int maxDepth(struct TreeNode* root) {
if(root==NULL) return 0;
int h1=maxDepth(root->left)+1;
int h2=maxDepth(root->right)+1;
if(h1<h2){
h1=h2;
}
return h1;
}