二叉树的结构体定义
struct TreeNode {
int val;
TreeNode *left;
TreeNode *right;
TreeNode() : val(0), left(nullptr), right(nullptr) {}
TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
};
二叉树的构建 这里采用层序遍历对二叉树进行插入操作(需要关注的点时,构建树时一般站在父节点的角度,防止丢失与根结点的联系,而遍历二叉树时可以站在当前结点去考虑问题。(这是本蒟蒻目前能达到的理解深度)
TreeNode* LevelOrder(TreeNode* p,int v) {
TreeNode* tmp = new TreeNode(v);
queue<TreeNode*> qt;
TreeNode* f = p;
if (!p) {
p = tmp;
cout << p->val << " ";
return p;
}
else {
qt.push(p);
while (!qt.empty()) {
f = qt.front();
qt.pop();
if (f->left) qt.push(f->left);
else if (!f->left) {
f->left = tmp;
cout << f->left->val << " ";
break;
}
if(f->right) qt.push(f->right);
else
{
f->right = tmp;
cout << f->right->val << " ";
break;
}
}
return p;
}
}
非递归先序遍历 //遍历树时一般基于当前结点,对于先序遍历,若当前结点存在则访问,并指向它的左孩子;若当前结点不存在,弹出一个结点,并指向该结点的右孩子。
void PreOrder(TreeNode* node) {
stack<TreeNode*> s;
TreeNode* p = node;
while (p || !s.empty()) {
if (p) {
cout << p->val<<" ";
s.push(p);
p = p->left;
}
else{
p = s.top();
s.pop();
p = p->right;
}
}
}
非递归中序遍历
void InOrder(TreeNode* node) {
stack<TreeNode*> s;
TreeNode* p=node;
while (p || !s.empty()) {
if (p) {
s.push(p);
p = p->left;
}
else {
p = s.top();
s.pop();
cout << p->val << " ";
p = p->right;
}
}
}
主函数如下:
int main() {
TreeNode* node=NULL;
for (int i = 0; i < 9; i++) {
node=LevelOrder(node,i);
}
PreOrder(node);
InOrder(node);
return 0;
}
后序遍历 以查找某结点的所有祖先为例
struct myStack {
TreeNode* t;
int tag;
};
void postOrder(TreeNode* node, int v) {
myStack *s = new myStack[9];
int top = 0;
while (node || top > 0) {
while (node&&node->val!=v) {
s[++top] = { node ,0};
node = node->left;
}
if (node && node->val == v) {
cout << "v的所有祖先:";
for(int i=1;i<top;i++){
cout << s[i].t->val << " ";
}
cout << endl;
return;
}
while (top > 0 || s[top].tag == 1) {
top--;
}
if (top > 0) {
s[top].tag = 1;
node = s->t->right;
}
}
}
|