构建这样一颗二叉树
树的结构
class Node
{
public:
Node() :m_left(NULL), m_right(NULL) {}
Node(char v) :m_value(v), m_left(NULL), m_right(NULL) {}
char m_value;
Node* m_left;
Node* m_right;
};
二叉树的构建
class Tree
{
public:
Node* m_root;
Tree() :m_root(NULL) {}
Node* CreateTree(const char*& str)
{
if (*str == '#')
return NULL;
else
{
Node* root = new Node(*str);//创建根
root->m_left = CreateTree(++str);
root->m_right = CreateTree(++str);
return root;
}
}
//void Create(Node *&root,const char *&str);
void PreOrder(Node* t)
{
if (t)
{
cout << t->m_value << " ";
PreOrder(t->m_left);
PreOrder(t->m_right);
}
}
void InOrder(Node* t)//左根右
{
if (t)
{
InOrder(t->m_left);
cout << t->m_value << " ";
InOrder(t->m_right);
}
}
void PostOrder(Node* t)//左右根
{
if (t)
{
PostOrder(t->m_left);
PostOrder(t->m_right);
cout << t->m_value << " ";
}
}
int Size(Node* t) //以t为根的树的结点个数=左子树+右子树+1(自己)
{
if (t == NULL)
return 0;
else
return Size(t->m_left) + Size(t->m_right) + 1;
}
int Height(Node* t) //以t为根的树的深度=左子树深度和右子树深度较大值+1
{
if (t == NULL)
return 0;
else
{
int hl = Height(t->m_left);
int hr = Height(t->m_right);
return hl > hr ? (hl + 1) : (hr + 1);
}
}
Node* Search(Node* t, char v) //查找值为v的结点,返回指向结点的指针
{
if (t == NULL)
return NULL;
if (t->m_value == v)
return t;
Node* p = Search(t->m_left, v);
if (p == NULL)
return Search(t->m_right, v);
}
Node* Search_parent(Node* t, char v)
{
Node* q = NULL;
if (t == NULL)
return NULL;
if (t->m_left != NULL && t->m_left->m_value == v ||
t->m_right != NULL && t->m_right->m_value == v)
return t;
q = Search_parent(t->m_left, v);
if (q != NULL)
return q;
return Search_parent(t->m_right, v);
}
void Copy(Node*& root1, Node*& root2)
{
if (root2 == NULL)
root1 = NULL;
else
{
root1 = new Node(root2->m_value);
Copy(root1->m_left, root2->m_left);
Copy(root1->m_right, root2->m_right);
}
}
void LevelOrder(Node* t);
void PreOrder_1(Node* t); // 先序遍历非递归
void InOrder_1(Node* t); //中序遍历非递归
void PostOrder_1(Node* t); //后序遍历非递归
};
层遍历
void Tree::LevelOrder(Node* t)
{
queue<Node*> qq;
Node* front = NULL;
if (t != NULL)
{
qq.push(t); //根入队
while (!qq.empty()) //如果队列不空
{
front = qq.front(); //获取队头,是为了保存下一层的孩子
qq.pop();
cout << front->m_value << " ";
//根据左右顺序将孩子入队
if (front->m_left != NULL)
qq.push(front->m_left);
if (front->m_right != NULL)
qq.push(front->m_right);
}
}
cout << endl;
}
非递归中序遍历
左根右,访问完最左边孩子,接着要访问它的父节点,所以得保存父节点,自然就能找到右子树
1.先将根以及根下面的所有的左子树全部入栈
2.判断栈是否为空,如果不空,获得栈顶出栈,并用p记住栈顶的右子树
3.查看当前p是否有左子树,如果有,则继续执行1,2,3步骤,直到p为空或者栈为空为止
void Tree::InOrder_1(Node* t)
{
if (t != NULL)
{
stack<Node*>ss;
Node* p = t;
Node* top = NULL;
while (p || !ss.empty())
{
while (p != NULL)
{
ss.push(p);
p = p->m_left;
}
if (!ss.empty())
{
top = ss.top();
ss.pop();
cout << top->m_value << " ";
p = top->m_right; //当前结点遍历完,记住右子树
}
}
}
cout << endl;
}
非递归先序遍历
1.将根入栈
2.栈不空,获取栈顶并出栈,然后按照右左顺序将当前结点的孩子入栈
原因:访问左子树,要将右子树保存到栈,为了左子树访问完后访问右子树
3.重复执行2操作,直到栈空为止
void Tree::PreOrder_1(Node* t)
{
stack<Node*> ss;
Node* top = NULL;
if (t != NULL)
{
ss.push(t);
while (!ss.empty())
{
top = ss.top();
ss.pop();
cout << top->m_value << " ";
if (top->m_right != NULL)
ss.push(top->m_right);
if (top->m_left != NULL)
ss.push(top->m_left);
}
}
cout << endl;
}
非递归后序遍历
左右根---根右左
注意:需要一个指针记住已经遍历过的结点(出去的结点)
原因:1.入栈:如果当前结点有左右孩子,则按照右左顺序入栈
出栈:1.如果当前结点没有左右孩子
2.当前结点有孩子,但是孩子已经遍历过了,则出栈
void Tree::PostOrder_1(Node* t)
{
if (t != NULL)
{
stack<Node*> ss;
Node* top = NULL, * pre = NULL;
ss.push(t);
while (!ss.empty())
{
top = ss.top();
if (top->m_left == NULL && top->m_right == NULL ||
pre != NULL && top->m_left == pre || pre != NULL && top->m_right == pre)
{
ss.pop();
cout << top->m_value << " ";
pre = top;
}
else
{
if (top->m_right != NULL)
ss.push(top->m_right);
if (top->m_left != NULL)
ss.push(top->m_left);
}
}
}
cout << endl;
}
主函数
void main()
{
Tree t;
Tree t1;
const char* str = "ABDG##HI####CE#J##F##";
t.m_root = t.CreateTree(str);
cout << "先序遍历:";
t.PreOrder(t.m_root);
cout << endl;
cout << "中序遍历:";
t.InOrder(t.m_root);
cout << endl;
cout << "后序遍历:";
t.PostOrder(t.m_root);
cout << endl;
cout << "size = " << t.Size(t.m_root) << endl;
cout << "Height = " << t.Height(t.m_root) << endl;
Node* p = t.Search(t.m_root, 'K');
if (p != NULL)
cout << "找到了p->value = " << p->m_value << endl;
else
cout << "没找到" << endl;
cout << "copy:" << endl;
t1.Copy(t1.m_root, t.m_root);
t1.PreOrder(t1.m_root);
cout << endl;
cout << "层次遍历:" << endl;
t.LevelOrder(t.m_root);
cout << "非递归先序遍历:" << endl;
t.PreOrder_1(t.m_root);
cout << "非递归中序遍历:" << endl;
t.InOrder_1(t.m_root);
cout << "非递归后序遍历:" << endl;
t.PostOrder_1(t.m_root);
}