c++学习笔记—二叉树基本操作的实现
用c++语言实现的二叉树基本操作,包括二叉树的创建、二叉树的遍历(包括前序、中序、后序递归和非递归算法)、求二叉树高度,计数叶子节点数、计数度为1的节点数等基本操作。
IDE:vs2013
具体实现代码如下:
- #include "stdafx.h"
- #include <malloc.h>
- #include <stack>
- #include <iostream>
- #define MAXSIZE 100
- using namespace std;
- typedef struct node //二叉树结构体
- {
- int data;
- struct node *lchild;
- struct node *rchild;
- }Bnode,*BTree;
- BTree CreateBinaryTree(BTree &tree){ //创建二叉树
- int inputdata;
- cin >> inputdata;
- if (-1 == inputdata)
- {
- tree = NULL;
- }
- else
- {
- if (!(tree = (Bnode*)malloc(sizeof(Bnode))))
- {
- cout<<"ERROR";
- }
- tree->data = inputdata;
- tree->lchild=CreateBinaryTree(tree->lchild);
- tree->rchild=CreateBinaryTree(tree->rchild);
- }
- return tree;
- }
- void preorderTraverse(BTree tree) //递归前序遍历
- {
- if (tree != NULL)
- {
- cout<<tree->data;
- }
- if (tree->lchild != NULL)
- {
- preorderTraverse(tree->lchild);
- }
- if (tree->rchild)
- {
- preorderTraverse(tree->rchild);
- }
- }
- void preorderTraverse2(BTree tree)
- {
- //////////////////////////////////////////////////////////////////////////
- // 非递归前序
- // 根据前序遍历访问的顺序,优先访问根结点,
- // 然后再分别访问左孩子和右孩子。
- // 即对于任一结点,其可看做是根结点,因此可以直接访问,访问完之后,
- // 若其左孩子不为空,按相同规则访问它的左子树;当访问其左子树时,
- // 再访问它的右子树。因此其处理过程如下:
- //
- //////////////////////////////////////////////////////////////////////////
- stack<BTree> s;
- if (!tree)
- {
- cout << "空树" << endl;
- return;
- }
- while (tree || !s.empty())
- {
- while (tree)
- {
- s.push(tree);
- cout << tree->data;
- tree = tree->lchild;
- }
- tree = s.top();
- s.pop();
- tree = tree->rchild;
- }
- }
- void inorderTraverse(BTree tree) //递归中序遍历
- {
- if (tree->lchild)
- {
- inorderTraverse(tree->lchild);
- }
- cout << tree->data;
- if (tree->rchild)
- {
- inorderTraverse(tree->rchild);
- }
- }
- void inorderTraverse2(BTree tree)
- {
- //////////////////////////////////////////////////////////////////////////
- // 非递归中序遍历
- // 根据中序遍历的顺序,对于任一结点,优先访问其左孩子,
- // 而左孩子结点又可以看做一根结点,然后继续访问其左孩子结点,
- // 直到遇到左孩子结点为空的结点才进行访问,
- // 然后按相同的规则访问其右子树。
- // 因此其处理过程如下:
- //
- ///////////////////////////////////////////////////////////////////////////
- stack<BTree> s;
- if (!tree)
- {
- cout << "空树" << endl;
- return;
- }
- while (tree || !s.empty())
- {
- while (tree)
- {
- s.push(tree);
- tree = tree->lchild;
- }
- tree = s.top();
- s.pop();
- cout << tree->data;
- tree = tree->rchild;
- }
- }
- void postoderTraverse(BTree tree) //递归后序遍历
- {
- if (tree->lchild)
- {
- postoderTraverse(tree->lchild);
- }
- if (tree->rchild)
- {
- postoderTraverse(tree->rchild);
- }
- cout << tree->data;
- }
- void postoderTraverse2(BTree tree)
- {
- //////////////////////////////////////////////////////////////////////////
- // 非递归后序遍历
- // 要保证根结点在左孩子和右孩子访问之后才能访问,
- // 因此对于任一结点P,先将其入栈。如果P不存在左孩子和右孩子,
- // 则可以直接访问它;或者P存在左孩子或者右孩子,
- // 但是其左孩子和右孩子都已被访问过了,则同样可以直接访问该结点。
- // 若非上述两种情况,则将P的右孩子和左孩子依次入栈,
- // 这样就保证了每次取栈顶元素的时候,左孩子在右孩子前面被访问,
- // 左孩子和右孩子都在根结点前面被访问。
- //////////////////////////////////////////////////////////////////////////
- stack<BTree> s;
- BTree cur; //当前结点
- BTree pre = NULL; //前一次访问的结点
- s.push(tree);
- while (!s.empty())
- {
- cur = s.top();
- if ((cur->lchild == NULL&&cur->rchild == NULL) ||(pre != NULL && (pre == cur->lchild || pre == cur->rchild)))
- {
- cout << cur->data; //如果当前结点没有孩子结点或者孩子节点都已被访问过
- s.pop();
- pre = cur;
- }
- else
- {
- if (cur->rchild != NULL)
- s.push(cur->rchild);
- if (cur->lchild != NULL)
- s.push(cur->lchild);
- }
- }
- }
- int Depth(BTree T) //求二叉树的深度
- {
- int dep = 0, depl, depr;
- if (!T) dep = 0;
- else
- {
- depl = Depth(T->lchild);
- depr = Depth(T->rchild);
- dep = 1 + (depl>depr ? depl : depr);
- }
- return dep;
- }
- int sumLeaf(BTree tree) //求叶子节点的个数
- {
- int sum = 0, m, n;
- if (tree)
- {
- if ((!tree->lchild) && (!tree->rchild))
- sum++;
- m = sumLeaf(tree->lchild);
- sum += m;
- n = sumLeaf(tree->rchild);
- sum += n;
- }
- return sum;
- }
- int numnSinglePoint(BTree tree ) //统计度为1的节点数目
- {
- int sum = 0, m, n;
- if (tree)
- {
- if ((tree->lchild!=NULL) && (tree->rchild == NULL))
- sum++;
- if ((tree->lchild == NULL) && (tree->rchild != NULL))
- sum++;
- m = numnSinglePoint(tree->lchild);
- sum += m;
- n = m = numnSinglePoint(tree->rchild);
- sum += n;
- }
- return sum;
- }
- int _tmain(int argc, _TCHAR* argv[])
- {
- BTree t;
- t= CreateBinaryTree(t);
- cout<<endl<<"非递归前序遍历:";
- preorderTraverse2(t);
- cout << endl<<"----------------------"<<endl;
- cout << "递归前序遍历:";
- preorderTraverse(t);
- cout << endl << "---------------------"<<endl;
- cout << "非递归中序遍历:";
- inorderTraverse2(t);
- cout << endl << "---------------------"<<endl;
- cout << "递归中序遍历:";
- inorderTraverse(t);
- cout << endl << "---------------------"<<endl;
- cout << "非递归后序遍历:";
- postoderTraverse2(t);
- cout << endl << "---------------------"<<endl;
- cout << "递归后序遍历:";
- postoderTraverse(t);
- cout << endl << "----------------------"<<endl;
- cout << "链表深度为:"<<Depth(t);
- cout << endl << "----------------------"<<endl;
- cout << "链表的叶子节点个数为:" << sumLeaf(t);
- cout << endl << "----------------------"<<endl;
- cout << "链表中度为1的节点数目为:" << numnSinglePoint(t) << endl;
- return 0;
- }
构建二叉树示意图为:
运行程序结果为: