题目
给定一棵二叉树中的一个节点,如何找出中序遍历列的下一个节点?(树中除了有左右节点的指针还有一个指向父节点的指针)
上图的二叉树中序遍历序列为;
[d,b,h,e,i,a,f,c,g]
观察二叉树的结构可知;
如果给定的节点有右子树,那么他的下一个节点是他的右子树的最左子节点
如果给定的节点没有右子树,如果他的节点是他父节点的左节点,那么他的下一个节点就是他的父节点
如果该给定的节点没有右子树,并且是他父节点的右节点。那么他的下一个节点要沿着父节点的指针一直向上遍历直到当前节点是父节点的左节点的位置,那么该节点中序遍历为下一个节点就是当前的父节点。
实现:
BTNode* searchextNode(BTNode *pNode){
if (!pNode){
return NULL;
}
BTNode *pNext = NULL;
//当前二叉树有右子树
if (pNode->right){
BTNode *pRight = pNode->right;
while (pRight->left){
pRight = pRight->left;
}
pNext = pRight;
}
//当前二叉树没有右子树
else if (pNode->pa){
BTNode *pC = pNode;
BTNode *pPa = pNode->pa;
while (pPa&&pPa->left != pC){
pC = pPa;
pPa = pPa->pa;
}
pNext = pPa;
}
return pNext;
}
测试:
//定义二叉树的节点
typedef struct node{
int data;
struct node *left;
struct node *right;
struct node *pa;
}BTNode;
//为了存储二叉树节点,采用了全局变量
int num = 0;
BTNode **f = (BTNode**)malloc(sizeof(BTNode*) * 8);
//创建带双亲指针的二叉搜索树
BTNode* creatBinSortTree(int data[], int len){
BTNode *root = NULL, *pa = NULL, *c = NULL;
for (int i = 0; i < len; i++){
BTNode *p = (BTNode*)malloc(sizeof(BTNode));
p->data = data[i];
p->left = p->right = p->pa = NULL;
if (!root){
root = p;
}
else{
c = root;
while (c){
pa = c;
if (c->data < p->data){
c = c->right;
}
else{
c = c->left;
}
}
if (pa->data < p->data){
pa->right = p;
}
else{
pa->left = p;
}
p->pa=pa;
}
}
return root;
}
//中序遍历二叉树
void InOrder(BTNode *root){
if (root){
InOrder(root->left);
//存储当前节点的地址
f[num++] = root;
printf("%d ",root->data);
InOrder(root->right);
}
}
int main(void){
int data[8] = { 3, 2, 5, 8, 4, 7, 6, 9 };
BTNode *root = creatBinSortTree(data, 8);
printf("中序遍历二叉树:");
InOrder(root);
for (int i = 0; i< 8; i++){
int next=-1;
if (searchextNode(f[i])){
next = searchextNode(f[i])->data;
}
printf("\n%p======%d--->next==%d\n ", f[i], f[i]->data,next);
}
system("pause");
return 0;
}
调试结果: