C++实现二叉树的直观打印,非递归实现前、中、后序遍历

废话不多说,直接上代码。工程中一共三个文件:main.cpp、MyNode.h、MyNode.cpp。二叉树采用类的方式进行创建。

//main.cpp函数
#include<iostream>
#include "MyNode.h"
using namespace std;

int main()
{
	MyNode *head = new MyNode(1);
	head->left = new MyNode(-222222222);
	head->right = new MyNode(3);
	head->left->left = new MyNode(8888);
	head->right->left = new MyNode(55555555);
	head->right->right = new MyNode(66);
	head->left->left->right = new MyNode(777);
	cout << "*********直观打印二叉树*********\n";
	MyNode::printTree(head);
    cout << "*********前序打印二叉树*********\n";
    MyNode::print_pre(head);
    cout << "\n*********中序打印二叉树*********\n";
    MyNode::print_mid(head);
    cout << "\n*********后序打印二叉树*********\n";
    MyNode::print_later(head);

	return 0;
}
//MyNode.h文件
#include <iostream>
#include <string>
#include <stack>//栈的头文件

using namespace std;
class MyNode
{
public:
    //构造函数
	MyNode(int data);
	//析构函数
	~MyNode();
	static string getSpace(int num);//获取一定空间函数,看起来更加好看,防止数据之间长短不一,造成错位
	static void printInOrder(MyNode *head, int height, string to, int len);
	//直观打印二叉树
	static void printTree(MyNode *head);//这里一定要加static,否则报错
	//前序打印二叉树
    static void print_pre(MyNode *head);
	//中序打印二叉树
    static void print_mid(MyNode *head);
	//后序打印二叉树
    static void print_later(MyNode *head);

    //成员变量
	int value;
	MyNode *left;
	MyNode *right;
};
//MyNode.cpp文件
#include "MyNode.h"
//构造函数的定义
MyNode::MyNode(int data)
{
	this->value = data;
	this->left = NULL;
	this->right = NULL;
}
//获取一定空间函数,看起来更加好看【不必纠结】
string MyNode::getSpace(int num) {
	string result = "";
	for (int i = 0; i < num; i++) {
		result.append(" ");//追加字符或字符串
	}
	return result;
}
//遍历二叉树
void MyNode::printInOrder(MyNode *head, int height, string to, int len) {
	if (head == NULL) {
		return;
	}
	printInOrder(head->right, height + 1, "v", len);//右子树
	string val = to + to_string(head->value) + to;//to_string函数将数值转化为字符串。返回对应的字符串
	int lenM = val.length();
	int lenL = (len - lenM) / 2;
	int lenR = len - lenM - lenL;
	val = getSpace(lenL) + val + getSpace(lenR);
	cout << (getSpace(height * len) + val) << "\n";
	printInOrder(head->left, height + 1, "^", len);//左子树
}
//打印二叉树
 void MyNode::printTree(MyNode *head) {
	printInOrder(head, 0, "H", 17);
	cout << endl;
}
//前序遍历的方式打印树的结点数据【非递归】
void MyNode::print_pre(MyNode *head)
{
    if(head == NULL)
        return;

    stack<MyNode*> s;
    s.push(head);
    while(!s.empty())
    {
        head = s.top();
        cout << head->value << " ";//返回第一个元素(栈顶元素)
        s.pop();//出栈操作(删除栈顶),只是出栈,没有返回值
        if(head->right != NULL)
        {
            s.push(head->right);
        }
        if(head->left != NULL)
        {
            s.push(head->left);
        }

    }
}
/**中序遍历的方式打印树的结点数据【非递归】
 *当前结点为空的话,先打印,然后当前结点右移【即变为原结点的右孩子】
 *当前结点不为空的话,当前结点压入栈中,然后当前结点左移【即变为原结点的左孩子】
 */
void MyNode::print_mid(MyNode *head)
{
    if(head != NULL)
    {
       stack<MyNode*> s;//申请一个存储树的栈
       while( !s.empty() || head != NULL)
       {
           if(head != NULL)
           {
               s.push(head);
               head = head->left;
           }
           else
           {
              head = s.top();
              cout << head->value << " ";//返回第一个元素(栈顶元素)
              s.pop();//出栈操作(删除栈顶),只是出栈,没有返回值

              head = head->right;
           }
       }
    }
}
/** 后序遍历的方式打印树的结点数据【非递归】
 * 由前序遍历的打印顺序可知为:中左右。很容易实现打印顺序为:中右左
 * 实现打印顺序为中右左后,元素把打印而是把其压入一个栈中,当所有的树结点遍历完了
 * 最后从栈中弹出,打印得到的顺序即为:左右中
 */
void MyNode::print_later(MyNode *head)
{
    if(head != NULL)
    {
       stack<MyNode*> s;//申请一个存储树的栈
       stack<MyNode*> S2;//临时栈
       s.push(head);
       while( !s.empty())
       {
           head = s.top();
           //cout << T->data << " ";//返回第一个元素(栈顶元素)
           //这里不打印,而是将树的结点压入栈中
           S2.push(head);
           s.pop();//出栈操作(删除栈顶),只是出栈,没有返回值
           if(head->left != NULL)
           {
                s.push(head->left);
           }
           if(head->right != NULL)
           {
                s.push(head->right);
           }
       }
       while( !S2.empty())
       {
           head = S2.top();
           cout << head->value << " ";//返回第一个元素(栈顶元素)
           S2.pop();//出栈操作(删除栈顶),只是出栈,没有返回值
       }
    }

}
//析构函数定义
MyNode::~MyNode()
{
}

最终运行的结果如下所示:【直观打印的二叉树需要把你的脑袋瓜逆时针转九十度。

怎么清晰地确定任何一个节点的父节点呢?

(1)如果一个节点打印结果的前缀与后缀都有“H",说明这个节点是头节点

(2)如果一个节点打印结果的前缀与后缀都有“v”,表示父节点在该节点所在列的前一列, 在该节点所在行的下方,并且是离该节点最近的节点。“v3v”、“v66v”和“v777v", 父节点分别为“HIH",“v3v”和“^8888^”。

(3)如果一个节点打印结果的前缀与后缀都有“^”,表示父节点在该节点所在列的前一列, 在该节点所在行的上方,并且是离该节点最近的节点。^-222222222^、^55555555^、^8888^,父节点分别为HIH、v3v、^-222222222^

 

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是c语言实现叉树镜像并打印的代码: ``` #include <stdio.h> #include <stdlib.h> //定义二叉树结构体 typedef struct TreeNode { int val; struct TreeNode *left; struct TreeNode *right; } TreeNode; //创建二叉树 TreeNode *createTree() { int val; scanf("%d", &val); if (val == -1) { return NULL; } TreeNode *node = (TreeNode *) malloc(sizeof(TreeNode)); node->val = val; node->left = createTree(); node->right = createTree(); return node; } //二叉树镜像 TreeNode *mirrorTree(TreeNode *root) { if (root == NULL) { return NULL; } TreeNode *temp = root->left; root->left = root->right; root->right = temp; mirrorTree(root->left); mirrorTree(root->right); return root; } //打印叉树) void printTree(TreeNode *root) { if (root == NULL) { return; } printTree(root->left); printf("%d ", root->val); printTree(root->right); } int main() { printf("请输入二叉树的节点(-1代表空节点):\n"); TreeNode *root = createTree(); printf("二叉树镜像:\n"); printTree(root); printf("\n"); TreeNode *newRoot = mirrorTree(root); printf("二叉树镜像后的:\n"); printTree(newRoot); printf("\n"); return 0; } ``` 代码思路: 1. 定义二叉树结构体,包括节点值和左右子节点。 2. 创建二叉树函数,通过实现,如果输入的节点值为-1,则返回NULL,否则继续创建左右子节点。 3. 二叉树镜像函数,通过实现,首先交换当节点的左右子节点,然后分别对左右子节点进行镜像操作。 4. 打印叉树函数,通过实现,先打印左子树,然后打印节点,最后打印右子树。 5. 在主函数,先创建二叉树,然后打印叉树镜像,接着调用二叉树镜像函数,得到镜像后的二叉树,最后打印叉树镜像后的

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值