牛客大佬的全ac代码
打印完全二叉树的边界
根据结点序号位置,依次打印非叶子的左边界,非右边界的叶子结点,非左边界的右边界。
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <queue>
#include <algorithm>
#include <vector>
#include <iomanip>
#include <unordered_map>
#include <unordered_set>
#include <map>
#include "limits.h"
#include "math.h"
using namespace std;
struct TreeNode{
int val;
TreeNode *left;
TreeNode *right;
TreeNode(int x):val(x), left(NULL),right(NULL){}
};
int main(int argc, const char * argv[]) {
vector<int> ledge; //非叶子的左边界:输入位置[0...n-1]中,符合2^n-1特点的结点
vector<int> leaf; //非右边界的叶子结点
vector<int> redge; //非叶子非边界的右边界:输入位置[0...n-1]中,符合2^n-2特点的结点
int n;
cin >> n;
int depth = (int)floor( log(n)/log(2) ); //log2(n)向下取整
int nonleafNum, leafNum;
//如果是满二叉树
bool isman = false;
if( (double)depth == (log(n)/log(2)) ){
isman = true;
}else{
depth += 1;
}nonleafNum = (int)pow(2, depth-1)-1; //非叶子结点个数:2^(depth-1)-1
leafNum = n - nonleafNum; //叶子结点的个数
//输入
int tree[n];
for(int i=0; i<n; i++){
cin >> tree[i];
}
// cout << endl << "d:" << depth << " nonleafNum:" << nonleafNum << " leafNum:" << leafNum<< endl;
//对于非叶子结点
for(int i=0; i<nonleafNum; i++){
//判断左边界
if( ( (i+1)&i ) == 0 ){
ledge.push_back(tree[i]);
}else if( ( (i+2)&(i+1) ) == 0 ){ //判断右边界
redge.push_back(tree[i]);
}
}
//叶子结点
for(int i=nonleafNum; i<n; i++){
leaf.push_back(tree[i]);
}
//如果不是满二叉树,那在上一层中可能还剩了叶子结点
//上一层中有孩子的结点的个数:(leafNum+1)/2,上一层的结点范围[2^(depth-2)-1, 2^(depth-1)-2],注意除掉左右边界
if( !isman ){
int num = (leafNum+1)/2;
// cout << "num:" << num;
int l = (int)pow(2, depth-2);
if( num >= 2 ){
l = l + (num-1);
}
int r = (int)pow(2, depth-1)-3;
// cout << " l:" << l << " r:" << r << endl;
for(int i=l; i<=r; i++){
leaf.push_back(tree[i]);
}
}
for(int i=0; i<ledge.size(); i++){
cout << ledge[i] << " ";
}
for(int i=0; i<leaf.size(); i++){
cout << leaf[i] << " ";
}
for(int i=redge.size()-1; i>=0; i--){
cout << redge[i] << " ";
}
cout << endl;
return 0;
}