#include <stdio.h>
#include <malloc.h>
/*
* 不用线索二叉树
* 就用普通二叉树
* 实现:
* 查找二叉树某个节点的: 中序前驱,中序后继
*/
/*
* 中序:
* 不用线索二叉树实现的话
* 就要中序遍历整个普通二叉树直到遍历到该结点的前驱和后继才能找到
*
* 中序: 左 根 右
* (pre)(该节点) (post)
*
* 所以:该节点的前驱永远都是在该节点前面一个被中序遍历到的
* 该节点的后继永远都是在该节点后面一个被中序遍历到的
*
* 所以:要中序遍历整个普通二叉树直到遍历到该结点的前驱和后继才能找到
*/
typedef struct BiNode
{
int data;
struct BiNode* lchild;
struct BiNode* rchild;
}BiNode,* BiTree;
//全局变量:指针 p:存储待查找二叉树结点的地址 ;指针pre:指向当前正在visit的的结点的前一个被visit过的结点(当前结点的前驱结点)
BiNode* p = (BiNode*)malloc(sizeof(BiNode));
BiNode* pre = NULL;
BiNode* final = NULL;//保存找到的前驱结点、后继结点的位置;
int flag = 0;//未查到到和指针p存储的待查找的二叉树结点的地址上存储的数据data是一样的的二叉树结点(未找到结点p)
//创建根节点
BiTree Init_BiTree()
{
int e;
BiTree N = (BiTree)malloc(sizeof(BiNode));//为根节点创建空间
printf("\n请输入该二叉树根节点的值:");
scanf_s("%d",&e);
N->data = e;
N->lchild = NULL;
N->rchild = NULL;
printf("\n根节点创建成功!");
return N;
}
//为结点T添加左孩子
void insert_BiNode_l(BiNode* &T)
{
int flag = 1;
printf("\n%d->lchild==NULL--1;%d->lchild==(int)--2:",T->data,T->data);
scanf_s("%d",&flag);
if (flag == 2)//该节点有左孩子
{
int e;
BiNode* child = (BiNode*)malloc(sizeof(BiNode));
printf("\n请输入 %d->lchild->data:", T->data);
scanf_s("%d", &e);
child->data = e;
child->lchild = NULL;
child->rchild = NULL;
T->lchild = child;
}
else//该节点没有左孩子
{
//空,啥都不干(因为本来每个结点的左孩子和右孩子都默认为NULL)
}
}
void insert_BiNode_r(BiNode* &T)
{
int flag = 1;
printf("\n%d->rchild==NULL--1;%d->rchild==(int)--2:", T->data, T->data);
scanf_s("%d", &flag);
if (flag == 2)//该节点有右孩子
{
int e;
BiNode* child = (BiNode*)malloc(sizeof(BiNode));
printf("\n请输入 %d->rchild->data:", T->data);
scanf_s("%d", &e);
child->data = e;
child->lchild = NULL;
child->rchild = NULL;
T->rchild = child;
}
else//该节点没有右孩子
{
//空,啥都不干(因为本来每个结点的左孩子和右孩子都默认为NULL)
}
}
//为已知的二叉树根节点构造二叉树(使用递归)
void creat_BiTree(BiTree &T)
{
if (T != NULL)
{
//为结点T添加左孩子
insert_BiNode_l(T);
creat_BiTree(T->lchild);
//为结点T添加右孩子
insert_BiNode_r(T);
creat_BiTree(T->rchild);
}
}
void vist(BiNode* T)
{
if (T->data == p->data)//当前正在访问的结点T与待查找的元素p->data相等(找到了)
{
//找到了结点p
flag = flag+1;//当flag==1时:当前正在遍历结点p,p的后继结点还在后一个visit;
//找前驱(当前正在visit的结点的前面一个已经遍历的结点)
//找后继//找后继(当前正在visit的结点的后面一个未遍历的结点)
final = pre;
printf("\n找到了 %d 的前驱:\n%p : %d\n",p->data,final,final->data);
}
else if (flag ==1)//当前正在visit的结点T是带查找结点p的后继(之前一次visit的是结点p,那么这次visit的结点就是结点p的后继)(左根右)
{
flag = 0;//恢复默认
final = T;
printf("\n找到了 %d 的后继:\n%p : %d\n", p->data, final, final->data);
}
else
{
printf(" %d ",T->data);
pre = T;
}
}
//中序遍历二叉树,并找到结点p的前驱和后继
void IN_ER(BiTree T)
{
if(T!=NULL)
{
IN_ER(T->lchild);
vist(T);
IN_ER(T->rchild);
}
}
void test_test()
{
int e;
BiTree T = Init_BiTree();
creat_BiTree(T);
printf("\n\n\n二叉树创建成功!");
printf("\n请输入带查找的结点的值:");
scanf_s("%d",&e);
p->data = e;
p->lchild = NULL;
p->rchild = NULL;
printf("\n");
IN_ER(T);
}
int main()
{
test_test();
return 0;
}
创建的二叉树如下:
运行结果: