赞
踩
目录
二叉树可采用顺序存储与链式存储,顺序存储的空间利用率较低,故一般采用链式存储。
链式存储结构描述如下:
- typedef struct BiTNode
- {
- ElemType data; //数据域
- struct BiTNode *lchild, *rchild; //左右孩子指针
- } BiTNode, *BiTree;
例如:输入二叉树的先序序列,即可得到一颗二叉树
例如:我们输入这颗二叉树的先序序列(空节点用0表示):1 2 0 4 6 0 0 0 3 0 5 0 0
然后我们输出任意几个结点的data数值,验证二叉树是否正确。
- #include<iostream>
- using namespace std;
- #define ElemType int
-
- typedef struct BiTNode
- {
- ElemType data;
- struct BiTNode *lchild, *rchild;
- } BiTNode, *BiTree;
-
- void createBiTree(BiTree& T)
- {
- ElemType d;
- cin >> d;
- if (d == 0)
- T = NULL;
- else
- {
- T = (BiTree)malloc(sizeof(BiTNode));
- T->data = d;
- createBiTree(T->lchild);
- createBiTree(T->rchild);
- }
- }
-
- int main()
- {
- BiTree root = NULL; //定义一棵空树
- cout << "请按先序序列输入各个结点(空节点用0表示):" << endl;
- createBiTree(root);
- //输出测试
- cout << "输出测试:" << endl;
- cout << root->lchild->data << endl;
- cout << root->lchild->rchild->lchild->data << endl;
- cout << root->rchild->rchild->data << endl;
- }
- void PerOrder(BiTree T)
- {
- if(T!=NULL)
- {
- cout << T->data << " "; //visit(root);
- PerOrder(T->lchild);
- PerOrder(T->rchild);
- }
- }
- void InOrder(BiTree T)
- {
- if(T!=NULL)
- {
- InOrder(T->lchild);
- cout << T->data << " "; //visit(root);
- InOrder(T->rchild);
- }
- }
- void PostOrder(BiTree T)
- {
- if(T!=NULL)
- {
- PostOrder(T->lchild);
- PostOrder(T->rchild);
- cout << T->data << " "; //visit(root);
- }
- }
仍以前面的二叉树为例,输入结点创建二叉树后,对其进行先序、中序、后序遍历输出:
- #include<iostream>
- using namespace std;
- #define ElemType int
-
- typedef struct BiTNode
- {
- ElemType data;
- struct BiTNode *lchild, *rchild;
- } BiTNode, *BiTree;
-
- void createBiTree(BiTree& T)
- {
- ElemType d;
- cin >> d;
- if (d == 0)
- T = NULL;
- else
- {
- T = (BiTree)malloc(sizeof(BiTNode));
- T->data = d;
- createBiTree(T->lchild);
- createBiTree(T->rchild);
- }
- }
-
- void PerOrder(BiTree T)
- {
- if(T!=NULL)
- {
- cout << T->data << " "; //visit(root);
- PerOrder(T->lchild);
- PerOrder(T->rchild);
- }
- }
-
- void InOrder(BiTree T)
- {
- if(T!=NULL)
- {
- InOrder(T->lchild);
- cout << T->data << " "; //visit(root);
- InOrder(T->rchild);
- }
- }
-
- void PostOrder(BiTree T)
- {
- if(T!=NULL)
- {
- PostOrder(T->lchild);
- PostOrder(T->rchild);
- cout << T->data << " "; //visit(root);
- }
- }
-
- int main()
- {
- BiTree root = NULL; //定义一棵空树
- cout << "请按先序序列输入各个结点(空节点用0表示):" << endl;
- createBiTree(root);
-
- //递归遍历
- cout << "先序遍历结果为:";
- PerOrder(root);
- cout << endl;
- cout << "中序遍历结果为:";
- InOrder(root);
- cout << endl;
- cout << "后序遍历结果为:";
- PostOrder(root);
- cout << endl;
- }
注意:递归遍历的特点是:
①每个节点都访问一次且仅访问一次;
②递归遍历中,递归工作栈的深度恰好为树的深度
以此棵二叉树为例:
我们借助栈来分析中序遍历(非递归)的访问过程:
|
先序遍历与中序遍历基本思想类似,只需把访问结点操作放在入栈操作前面即可,具体参考下面的代码。
后续遍历的非递归实现是三种遍历中最难的,具体思路为:
|
代码
- #include<iostream>
- #include <stack>
- using namespace std;
- #define ElemType int
-
- typedef struct BiTNode
- {
- ElemType data;
- struct BiTNode *lchild, *rchild;
- } BiTNode, *BiTree;
-
- void createBiTree(BiTree& T)
- {
- ElemType d;
- cin >> d;
- if (d == 0)
- T = NULL;
- else
- {
- T = (BiTree)malloc(sizeof(BiTNode));
- T->data = d;
- createBiTree(T->lchild);
- createBiTree(T->rchild);
- }
- }
-
- //先序遍历
- void PerOrder2(BiTree T)
- {
- stack<BiTree> S;
- BiTree p = T;
- while (p || !S.empty())
- {
- if (p)
- {
- cout << p->data << " "; //visit(p);
- S.push(p);
- p = p->lchild;
- }
- else
- {
- p = S.top();
- S.pop();
- p = p->rchild;
- }
- }
- }
-
- //中序遍历
- void InOrder2(BiTree T)
- {
- stack<BiTree> S; // #include<stack>
- BiTree p = T; //p是遍历指针
- while (p || !S.empty())
- {
- if (p)
- {
- S.push(p);
- p = p->lchild;
- }
- else
- {
- p = S.top();
- S.pop(); //栈顶元素出栈
- cout << p->data << " "; //visit(p);
- p = p->rchild; //转向出栈结点的右子树
- }
- }
- }
-
- //后序遍历
- void PostOrder2(BiTree T)
- {
- stack<BiTree> S;
- BiTree p = T, r = NULL; //r是辅助指针,指向最近访问过的结点
- while (p || !S.empty())
- {
- if (p)
- {
- S.push(p);
- p = p->lchild;
- }
- else
- {
- p = S.top();
- if (p->rchild && p->rchild != r) //若右子树存在,且未被访问过
- p = p->rchild;
- else
- {
- S.pop();
- cout << p->data << " "; //visit(p);
- r = p; //记录最近访问过的结点
- p = NULL; //结点访问完后,重置p指针
- }
- }
- }
- }
-
- int main()
- {
- BiTree root = NULL; //定义一棵空树
- cout << "请按先序序列输入各个结点(空节点用0表示):" << endl;
- createBiTree(root);
-
- //非递归遍历
- cout << "先序遍历(非递归)结果为:";
- PerOrder2(root);
- cout << endl;
- cout << "中序遍历(非递归)结果为:";
- InOrder2(root);
- cout << endl;
- cout << "后序遍历(非递归)结果为:";
- PostOrder2(root);
- cout << endl;
- }
要进行层次遍历,需要借助一个队列。先将二叉树根结点入队,然后出队,访问出队结点,若它有左子树,则将左子树根结点入队;若它有右子树,则将右子树根结点入队。然后出队,访问出队结点……如此反复,直至队列为空。
- void LevelOrder(BiTree T)
- {
- queue<BiTree> Q; //#include<queue>
- BiTree p;
- Q.push(T); //将根节点入队
- while (!Q.empty()) //队列不空则循环
- {
- p = Q.front();
- Q.pop(); //队头结点出队
- cout << p->data << " "; //visit(p);
- if (p->lchild != NULL)
- Q.push(p->lchild);
- if (p->rchild != NULL)
- Q.push(p->rchild);
- }
- }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。