首先引入树的概念,在链表中我们讨论的是一对一的线性结构,而在生活中,我们有很多一对多的情况需要处理,所以引入了树的概念。
树是n个结点的有限集,n=0的时候成为空树,在任意一课非空树中,有且仅有一个特定的点称为根(root)的结点,当n>1时,其余结点可以分为M个互不相交的有限集T1,T2....,其中每一个有限集本身又是一颗树,并且称为根的字数。
而二叉树,则是一种特别重要的树的类型
二叉树则是有穷节点的集合,可以为空,由根节点和称为其左子树和右子树的结点的两个不相交的二叉树组成, 二叉树的子树有左右之分
二叉树中又有特殊的完全二叉树,斜二叉树,完美二叉树(满二叉树)
二叉树的定义
struct BiTNode
{
ElemType data;
BiTNode *lchild,*rchild;
}*BiTree;
这里插一句题外话在定义数据结构时
*BiTree 等价于 typedef BiTNode *BiTree;
类似于 int *a;
二叉树的先序遍历
bool PreOrderTraverse(BiTree &T) //BiTree &T 等价于 BiTNode *&T;这是一个指向指针的引用
{
if(T==NULL)
{
return true;
}
vist(T); //访问根节点
PreOrderTraverse(T->lchild); //递归访问左孩子
PreOrderTraverse(T->rchild);
return true;
}
我们需要了解递归的基本思想 就很好理解上面这个代码了 在判断T不为空后,访问现在的根节点,然后传入T的左孩子,在判断T为不为空,访问节点,再传入左孩子,直到传入T->lchild为空则返回上一层。
二叉树的中序遍历
bool PreOrderTraverse(BiTree &T)
{
if(T==NULL)
{
return true;
}
PreOrderTraverse(T->lchild); //递归访问左孩子
vist(T); //访问根节点
PreOrderTraverse(T->rchild);
return true;
}
二叉树的后序遍历
bool PreOrderTraverse(BiTree &T)
{
if(T==NULL)
{
return true;
}
PreOrderTraverse(T->lchild); //递归访问左孩子
PreOrderTraverse(T->rchild);
vist(T); //访问根节点
return true;
}
三种算法的时间复杂度 O(n),空间复杂度O(n).
非递归中序遍历
void InOrderTraversal(BinTree &T)
{
//创建一个堆栈
SqStack s;
InitSqStack(S); //初始化
BiTree p = T;
while( p || !IsEmpty(S))
{
if(p)
{
Push(S, p); //一直向左沿途压入堆栈
p = p->lchild;
}
else
{
Pop(S, p); //弹出栈
visit(p); //打印结点
p = p->rchild; //访问节点右孩子
}
}
}
二叉树的层序遍历
//1. 根节点入队
//2. 从队列中取出一个元素
//3. 访问该元素的结点
//4. 若该元素所指的左右孩子不为空,则将其左右孩子的指针顺序入队
void LevelOrderTraversal(BiTree &T)
{
SqQueue Q;
InitsqQueue(Q);
if(!T)
{
return; //若是空直接返回
}
BiTree p;
PushQueue(Q,T);
while(!QueueEmpty(Q))
{
//将根节点出队
DeQueue(Q,p);
//访问根结点
cout << p->data << endl;
//if判断,是否能将根结点的左右孩子进队
if (p->lchild != nullptr)
{
PushQueue(Q, p->lchild);
}
if (p->rchild != nullptr)
{
PushQueue(Q, p->rchild);
}
}
}
二叉树的遍历 :输出二叉树的叶子结点
bool PreOrderTraverse(BiTree &T) //我们这里只需要判断是否有左右孩子结点才输出
{
if(T==NULL)
{
return true;
}
if(!T->lchild &&! T->rhild)
{
vist(T); //访问根节点
}
PreOrderTraverse(T->lchild); //递归访问左孩子
PreOrderTraverse(T->rchild);
return true;
}
二叉树的高度
int Depth(BiTree &T)
{
if(T == nullptr)
{
return 0;
}
int m = Depth(T->lchild);
int n = Depth(T->rchild);
if(m>n)
return m+1;
else
return n+1;
}
未完待续...........