二叉树可以使用数组和链表进行构建,但数组构建的是只有一个子树的二叉树时会造成极大的内存浪费,因此使用链表对二叉树进行构建
使用C++创建二叉树和其基本操作_孤城寻欢的博客-优快云博客
1.定义链表结构体TreeNode
typedef struct TreeNode{
int val;//该指针的值
TreeNode *left;//该指针的左孩子
TreeNode *right;//该指针的右孩子
// TreeNode(int x):val(x),left(NULL),right(NULL){} //构造函数
}*Tree,Node;
typedef的作用
typedef 可以为自定义的数据类型取一个新的名字
*Tree和Node是结构体TreeNode的别名,只是Tree是指针类型
在为结构体创建具体对象时可以使用别名来代替
构造函数
构造函数若不写则程序自动生成一个默认构造函数
存疑:当构造函数使用时,编译时报错Node未被定义,待解决
2.输入一个包含二叉树节点的数组及实例化结构体对象
输入一个包含二叉树节点的数组,叶子节点的左右指针用-1代替
int main(){
vector<int> vec={1,2,4,-1,-1,5,-1,-1,3,6,-1,-1,7,-1,-1};//前序输入二叉树,叶子节点的左右指针用-1代替
Tree T;//创建结构体,命名为T,等价于struct TreeNode *T
}
Tree T的含义
由于构建结构体时就已经起了别名Tree,因此Tree等价于struct TreeNode *,T对实例化的对象名
3.前序构造二叉树
int i=0;//定义全局变量i,用于访问数组
void create(Tree& T,vector<int>& vec){
int x=vec[i++];//如果i作为迭代的参数,则递归返回时i也跟着回到原来的数,因此要在取值时就修改i的变量
//叶子节点
if(x==-1){
T=NULL;
return;
}else{
T = new Node;//在堆区创建空间,T指向其空间首地址
T->val=x;
create(T->left,vec);//递归寻找左子树
create(T->right,vec);//递归寻找右子树
}
}
i不能作为形参进行递归,因为递归返回时i值回到递归之前的i值
构造完成
完整代码如下
#include<iostream>
#include<vector>
using namespace std;
typedef struct TreeNode{
int val;
TreeNode *left;
TreeNode *right;
// TreeNode(int x):val(x),left(NULL),right(NULL){} //构造函数
}*Tree,Node;
int i=0;
void create(Tree& T,vector<int>& vec){
int x=vec[i++];//如果i作为迭代的参数,则递归返回时i也跟着回到原来的数,因此要在取值时就修改i的变量
//叶子节点
if(x==-1){
T=NULL;
return;
}else{
T = new Node;//在堆区创建空间,T指向其空间首地址
T->val=x;
create(T->left,vec);//递归寻找左子树
create(T->right,vec);//递归寻找右子树
}
}
int main(){
Solution solution;
vector<int> vec={1,2,4,-1,-1,5,-1,-1,3,6,-1,-1,7,-1,-1};//前序输入二叉树,叶子节点的左右指针用-1代替
Tree T;//创建结构体,命名为T,等价于struct TreeNode *T
}
前序遍历-递归
class Solution {
public:
//遍历二叉树,将符合的元素加入数组vec中
void traversal(TreeNode* cur,vector<int>& vec){
//遇到空指针时,说明一条路已经走完
if(cur==NULL){
return;
}
//递归
vec.push_back(cur->val);//中
traversal(cur->left,vec);//左
traversal(cur->right,vec);//右
}
vector<int> preorderTraversal(TreeNode* root) {
vector<int> result;
traversal(root,result);
return result;
}
};
完整代码如下(ACM模式)
#include<iostream>
#include<vector>
using namespace std;
typedef struct TreeNode{
int val;
TreeNode *left;
TreeNode *right;
// TreeNode(int x):val(x),left(NULL),right(NULL){} //构造函数
}*Tree,Node;
int i=0;
void create(Tree& T,vector<int>& vec){
int x=vec[i++];//如果i作为迭代的参数,则递归返回时i也跟着回到原来的数,因此要在取值时就修改i的变量
//叶子节点
if(x==-1){
T=NULL;
return;
}else{
T = new Node;//在堆区创建空间,T指向其空间首地址
T->val=x;
create(T->left,vec);//递归寻找左子树
create(T->right,vec);//递归寻找右子树
}
}
class Solution {
public:
//遍历二叉树,将符合的元素加入数组vec中
void traversal(TreeNode* cur,vector<int>& vec){
//遇到空指针时,说明一条路已经走完
if(cur==NULL){
return;
}
vec.push_back(cur->val);//中
traversal(cur->left,vec);//左
traversal(cur->right,vec);//右
}
vector<int> preorderTraversal(TreeNode* root) {
vector<int> result;
traversal(root,result);
return result;
}
};
int main(){
Solution solution;
vector<int> vec={1,2,4,-1,-1,5,-1,-1,3,6,-1,-1,7,-1,-1};//前序输入二叉树,叶子节点的左右指针用-1代替
Tree T;//创建结构体,命名为T,等价于struct TreeNode *T
create(T,vec);//前序构造二叉树
vector<int> r=solution.preorderTraversal(T);//前序遍历二叉树,并以数组类型返回
//打印结果
for(int i=0;i<r.size();i++){
cout<<r[i]<<" ";
}
}

中序遍历-递归
class Solution {
public:
void traversal(TreeNode* cur,vector<int>& vec){
if(cur==NULL){
return;
}
traversal(cur->left,vec);//左
vec.push_back(cur->val);//中
traversal(cur->right,vec);//右
}
vector<int> inorderTraversal(TreeNode* root) {
vector<int> result;
traversal(root,result);
return result;
}
};
完整代码如下(ACM模式)
#include<iostream>
#include<vector>
using namespace std;
typedef struct TreeNode{
int val;
TreeNode *left;
TreeNode *right;
// TreeNode(int x):val(x),left(NULL),right(NULL){} //构造函数
}*Tree,Node;
int i=0;
void create(Tree& T,vector<int>& vec){
int x=vec[i++];//如果i作为迭代的参数,则递归返回时i也跟着回到原来的数,因此要在取值时就修改i的变量
//叶子节点
if(x==-1){
T=NULL;
return;
}else{
T = new Node;//在堆区创建空间,T指向其空间首地址
T->val=x;
create(T->left,vec);//递归寻找左子树
create(T->right,vec);//递归寻找右子树
}
}
class Solution {
public:
void traversal(TreeNode* cur,vector<int>& vec){
if(cur==NULL){
return;
}
traversal(cur->left,vec);//左
vec.push_back(cur->val);//中
traversal(cur->right,vec);//右
}
vector<int> inorderTraversal(TreeNode* root) {
vector<int> result;
traversal(root,result);
return result;
}
};
int main(){
Solution solution;
vector<int> vec={1,2,4,-1,-1,5,-1,-1,3,6,-1,-1,7,-1,-1};//前序输入二叉树,叶子节点的左右指针用-1代替
Tree T;//创建结构体,命名为T,等价于struct TreeNode *T
create(T,vec);//前序构造二叉树
vector<int> r=solution.inorderTraversal(T);//前序遍历二叉树,并以数组类型返回
//打印结果
for(int i=0;i<r.size();i++){
cout<<r[i]<<" ";
}
}

后序遍历-递归
class Solution {
public:
void traversal(TreeNode* cur,vector<int>& vec){
if(cur==NULL){
return;
}
traversal(cur->left,vec);//左
traversal(cur->right,vec);//右
vec.push_back(cur->val);//中
}
vector<int> postorderTraversal(TreeNode* root) {
vector<int> result;
traversal(root,result);
return result;
}
};
完整代码如下(ACM模式)
#include<iostream>
#include<vector>
using namespace std;
typedef struct TreeNode{
int val;
TreeNode *left;
TreeNode *right;
// TreeNode(int x):val(x),left(NULL),right(NULL){} //构造函数
}*Tree,Node;
int i=0;
void create(Tree& T,vector<int>& vec){
int x=vec[i++];//如果i作为迭代的参数,则递归返回时i也跟着回到原来的数,因此要在取值时就修改i的变量
//叶子节点
if(x==-1){
T=NULL;
return;
}else{
T = new Node;//在堆区创建空间,T指向其空间首地址
T->val=x;
create(T->left,vec);//递归寻找左子树
create(T->right,vec);//递归寻找右子树
}
}
class Solution {
public:
void traversal(TreeNode* cur,vector<int>& vec){
if(cur==NULL){
return;
}
traversal(cur->left,vec);//左
traversal(cur->right,vec);//右
vec.push_back(cur->val);//中
}
vector<int> postorderTraversal(TreeNode* root) {
vector<int> result;
traversal(root,result);
return result;
}
};
int main(){
Solution solution;
vector<int> vec={1,2,4,-1,-1,5,-1,-1,3,6,-1,-1,7,-1,-1};//前序输入二叉树,叶子节点的左右指针用-1代替
Tree T;//创建结构体,命名为T,等价于struct TreeNode *T
create(T,vec);//前序构造二叉树
vector<int> r=solution.postorderTraversal(T);//前序遍历二叉树,并以数组类型返回
//打印结果
for(int i=0;i<r.size();i++){
cout<<r[i]<<" ";
}
}
