非递归层次遍历方法实现二叉树中指定节点的层次数查找

  1. 数据结构教材中,提供了基于队列实现一个二叉树的非递归层次遍历算法。但对于一个任意二叉树,如果要查找其中任何一个节点所在的层次数,教科书中并没有给出基于层次遍历的非递归算法。鉴于层次遍历算法比较容易理解,因此本人基于层次遍历的非递归算法,进行适当改造修改,实现了二叉树中指定节点层次数定位的非递归层次遍历算法。
  2. 基本数据结构定义、操作与算法实现:

/*二叉树结构定于与相关算法*/

typedef struct BiNode
{
ElemType data;
struct BiNode *lChild, *rChild;
}BitTree, *pBT;
/*
建立二叉树。对于数值型数据,以输入-1安排对应的空指针;对于字符型数据,以输入空格符安排对应的空指针。
以数值型数据为例建立一棵二叉树的递归算法
*/
BitTree *CreBiTree(void)
{
BitTree *bt;
ElemType x;
scanf_s(“%d”, &x);
if (x == -1) bt = NULL;
else
{
bt = (BitTree *)malloc(sizeof(BitTree));
bt->data = x;
bt->lChild = CreBiTree();
bt->rChild = CreBiTree();
}
return bt;
}

/*
建立用来操作二叉树节点的队列
队列的数据结构表示与实现,使用链队列形式
包括操作:初始化,取队长,判断队空,取队头元素,入队和出队
*/
typedef struct qBtNode{
BitTree btData;
struct qBtNode *next;
}qBtLink;
typedef struct{
qBtLink *front;
qBtLink *rear;
}LinkBtQueue;
void initBtQueue(LinkBtQueue *LQ)
{
LQ->front = LQ->rear = (LinkBtQueue *)malloc(sizeof(LinkBtQueue));
LQ->front->next = NULL;
}

int isEmptyBtQue(LinkBtQueue *LQ)
{
if (LQ->front == LQ->rear) return 1;
return 0;
}
void enBtQueue(LinkBtQueue *LQ, BitTree *btNode)
{
qBtLink *p;
p = (qBtLink *)malloc(sizeof(qBtLink));
p->btData = *btNode;
p->next = NULL;
if (LQ->front == NULL) LQ->front->next = p;
LQ->rear->next = p;
LQ->rear = p;
}
int outBtQueue(LinkBtQueue *LQ, BitTree *btNode)
{
qBtLink *p;
if (LQ->front == LQ->rear) return 0;
p = LQ->front->next;
*btNode = p->btData;
LQ->front->next = p->next;
if (LQ->rear == p) //队列中只有一个元素时,需要重新修改队尾指针
LQ->rear=LQ->front;
free(p);
return 1;
}

/*

以层次遍历的非递归方法,实现指定节点值的层次数定位

已知一棵二叉树以二叉链表结构存储,试编制算法计算给定结点所在的层次

*/

int NonRecurlevelBT(pBT bt, ElemType x)

{

LinkBtQueue lQ1,lQ2;
//使用两个队列,一个出队,如果有左右子树就入另一个队,当前面队列为空时,然后对另一个队出队处理,循环处理同前

int iLevel=0,isFind=0,isLoop;//iLevel用来保存层次数值,isFind用来标记是否找到,isLoop用来标志是否进入循环(一个队列处理循环代表一个树的一层)

BitTree p;

initBtQueue(&lQ1);

initBtQueue(&lQ2);

if (bt)
enBtQueue(&lQ1, bt);

iLevel = 0;

while (!isFind && (!isEmptyBtQue(&lQ1) || !isEmptyBtQue(&lQ2)))

{

while (!isFind && !isEmptyBtQue(&lQ1))

{

isLoop = 1;

outBtQueue(&lQ1, &p);

if (p.data == x)

{

isFind = 1;

break;

}

if (p.lChild) enBtQueue(&lQ2, p.lChild);

if (p.rChild) enBtQueue(&lQ2, p.rChild);

}

if (isLoop) { iLevel++; isLoop = 0; }

while (!isFind && !isEmptyBtQue(&lQ2))

{

isLoop = 1;

outBtQueue(&lQ2, &p);

if (p.data == x)

{

isFind = 1;

break;

}

if (p.lChild) enBtQueue(&lQ1, p.lChild);

if (p.rChild) enBtQueue(&lQ1, p.rChild);

}

if (isLoop) { iLevel++; isLoop = 0; }

}

if (isFind) return iLevel;

else return 0;

}

    原文作者:二叉查找树
    原文地址: https://blog.csdn.net/dofar/article/details/50354601
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞