递归版建树、前序遍历输入,输出中序及后序
#include<bits/stdc++.h>
using namespace std;
typedef struct node1{
int v;
struct node1* left;
struct node1* right;
}node1,*tree;
void buildtree(tree &root){
int x;
cin>>x;
if(x == 0){//0表示空节点
root = NULL;
}
else{
root = (node1*)malloc(sizeof(node1));
if(!root)
exit(1);
root->v = x;
buildtree(root->left);
buildtree(root->right);
}
}
void preprint(node1* root){
if(!root)
return;
printf("%d ",root->v);
preprint(root->left);
preprint(root->right);
}
void inprint(node1* root){
if(!root)
return;
inprint(root->left);
printf("%d ",root->v);
inprint(root->right);
}
void nextprint(node1* root){
if(!root)
return;
nextprint(root->left);
nextprint(root->right);
printf("%d ",root->v);
}
int main(){
node1 *root;
buildtree(root);
preprint(root);
cout<<endl;
inprint(root);
cout<<endl;
nextprint(root);
system("pause");
return 0;
}
三种遍历、迭代实现
前序遍历、根左右
class Solution {
public:
vector<int> preorderTraversal(TreeNode* root) {
vector<int>ans;
if(root == NULL)
return ans;
stack<TreeNode*>s;
s.push(root);
while(!s.empty()){
TreeNode* tem = s.top();
s.pop();
ans.push_back(tem->val);
if(tem->right)//先置入右节点再置入左节点,保证遍历顺序是根左右
s.push(tem->right);
if(tem->left)
s.push(tem->left);
}
return ans;
}
};
中序遍历、左根右
class Solution {
public:
vector<int> inorderTraversal(TreeNode* root) {
vector<int>ans;
if(root == NULL)
return ans;
stack<TreeNode*>s;
do{
while(root){//一直循环到左子树为空时
s.push(root);
root = root->left;
}
if(!s.empty()){
TreeNode* tem = s.top();
s.pop();
ans.push_back(tem->val);
root = tem->right;
}
}while(root || !s.empty());
return ans;
}
};
后序遍历、左右根
class Solution {
public:
vector<int> postorderTraversal(TreeNode* root) {
vector<int>ans;
if(root == NULL)
return ans;
stack<TreeNode*>s;
s.push(root);
while(!s.empty()){
TreeNode* tem = s.top();
s.pop();
if(tem->left)//先入左树
s.push(tem->left);
if(tem->right)//再入右树
s.push(tem->right);
ans.push_back(tem->val);
}
reverse(ans.begin(), ans.end());//将序列翻转则形成后序
return ans;
}
};
//类似前序遍历进行相关的栈操作。但为了对应需改变左右子树的入栈顺序,最后翻转得到答案
前序遍历、建树
void buildtree(tree &root){
int x;
cin>>x;
if(x == 0){//输入0表示空节点
root = NULL;
}
else{
root = (node1*)malloc(sizeof(node1));
if(!root)
exit(1);
root->v = x;
buildtree(root->left);
buildtree(root->right);
}
}
通过中序遍历和后序遍历求出前序遍历
#include<bits/stdc++.h>
using namespace std;
void putans(string s1,string s2){
if(s1.size() > 0){
char root = s2[s2.size() - 1];//后序遍历的最后是根
cout<<root;//需求前序遍历,先输出根元素
int pos = s1.find(root);//在中序遍历找到根位置,分割出左右子树
putans(s1.substr(0,pos),s2.substr(0,pos));//对左子树递归继续求解
putans(s1.substr(pos+1),s2.substr(pos,s1.size()-pos-1));//对右子树递归继续求解
}
}
int main(){
string s1,s2;
cin>>s1;
cin>>s2;
putans(s1,s2);
cout<<endl;
return 0;
}
/*
substr(*要切割的字符串的起始位置*,*切割长度*)
*/
判断一棵树是否是完全二叉树
#include<bits/stdc++.h>
using namespace std;
typedef struct ListNode{
int val;
struct ListNode* left;
struct ListNode* right;
}node1,*tree;
void buildtree(tree &root){
int x;
cin>>x;
if(x == 0){//0表示空节点
root = (node1*)malloc(sizeof(node1));
root->val = 0;
root->left = NULL;
root->right = NULL;
}
else{
root = (node1*)malloc(sizeof(node1));
if(!root)
exit(1);
root->val = x;
buildtree(root->left);
buildtree(root->right);
}
}
int judge(ListNode* root){
queue<ListNode*>q;
q.push(root);
int flag = 0;
while(!q.empty()){
int cnt = q.size();
for(int i = 0;i < cnt;i++){
ListNode*t = q.front();
q.pop();
if(t->val == 0){
flag = 1;
break;
}
if(t->left)
q.push(t->left);
if(t->right)
q.push(t->right);
}
if(flag)
break;
}
while(!q.empty()){
ListNode*t = q.front();
q.pop();
if(t->val != 0)
return 0;
}
return 1;
}
int main(){
ListNode*root;
buildtree(root);
cout<<judge(root);
}
- 此次建树需要记录表示为空的零节点
- 在层序遍历中,当出队节点为空(即值为0)时,退出遍历。然后检查队列中是否存在非零节点,如有则不是完全二叉树
提供两组样例供读者使用:
TIPS1:1 5 8 0 0 0 6 0 0 return 1
TIPS2:1 5 0 0 8 0 6 0 0 return 0