输入一棵二元查找树,将该二元查找树转换成一个排序的双向链表。要求不能创建任何新的结点,只调整指针的指向。...

本文介绍了如何通过中序遍历来将二元查找树转换为排序的双向链表,详细解释了关键步骤和注意事项,包括递归函数的设计、节点初始化、环境恢复等。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目:输入一棵二元查找树,将该二元查找树转换成一个排序的双向链表。要求不能创建任何新的结点,只调整指针的指向。
  比如将二元查找树
10
/ \
614
/ \ / \
4812 16
转换成双向链表
4=6=8=10=12=14=16。

/*

1.二叉树中序遍历的结果与链表的顺序一致,所以可以采用中序遍历的方法来修改二叉树的指针

2.该题的关键是,如何将左子树的最大值与右子树的最小值通过根root连接起来,比如题目的8和12,这也是细节部分

3.写递归程序最重要的是弄明白递归进入的条件、递归返回的状态,如果递归进入时改变了环境,返回时应当恢复环境,就像栈的操作一样

4.使用指针变量时,要记得初始化

5.该算法没有返回链表头,而是返回了root。

*/

以下图片为测试结果:

/*节点定义*/ typedef struct node { char value; struct node *left; struct node *right; }BSTree; /*查找以tr为根最左边的节点,即以tr为根的二叉排序树的最小值*/ BSTree *findLeft(BSTree *tr) { BSTree*p = NULL; while(tr->left) { p= tr->left; tr= p; } return tr; } /*查找以tr为根最右边的节点,即以tr为根的二叉排序树的最大值*/ BSTree *findRight(BSTree *tr) { BSTree*p = NULL; while(tr->right) { p= tr->right; tr= p; } return tr; } /*实现将二叉排序树数转变为双链表*/ BSTree *ConvertBSTreeToList(BSTree **root) { if(!*root) return (BSTree *)NULL; BSTree*lt=NULL,*rt=NULL; if((*root)->right)/*先处理右子树,其实先处理左子树也行*/ { rt= ConvertBSTreeToList(&(*root)->right);/*递归进入*/ if((*root)->right)/*递归返回处理,如果该根节点的右子树有最小值,则将该最小值的节点与root连起来,否则直接处理*/ lt= findLeft((*root)->right); if(lt)rt = lt; if(rt) { rt->left= *root; (*root)->right= rt; } } if((*root)->left) { lt= ConvertBSTreeToList(&(*root)->left);/*递归进入*/ if((*root)->left)/*递归返回处理,如果该根节点的左子树有最大值,则将该最大值的节点与root连起来,否则直接处理*/ rt= findRight((*root)->left); if(rt)lt = rt; if(lt) { lt->right= *root; (*root)->left= lt; } } return *root; } /*递归创建二叉排序树,以','结束*/ void CreateBSTree(BSTree**tr) { BSTree*p = (BSTree *)malloc(sizeof(node)); scanf_s("%c",&p->value); p->left= NULL; p->right= NULL; if(p->value != ',') { if(!(*tr)) { *tr= p; (*tr)->left= NULL; (*tr)->right= NULL; } }else return; CreateBSTree(&(*tr)->left); CreateBSTree(&(*tr)->right); } int _tmain(int argc, _TCHAR* argv[]) { BSTree*binaryTree = NULL,*list = NULL; CreateBSTree(&binaryTree); list= ConvertBSTreeToList(&binaryTree); BSTree*p = list; while(list->left) { p= list->left; list= p; } while(p) { printf("%c",p->value); p= p->right; } for(;;); return 0; }


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值