剑指OFFER之二叉搜索树与双向链表(九度OJ1503)
题目描述:
-
输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的双向链表。要求不能创建任何新的结点,只能调整树中结点指针的指向。
- 输入:
-
输入可能包含多个测试样例。
对于每个测试案例,输入的第一行为一个数n(0<n<1000),代表测试样例的个数。
接下来的n行,每行为一个二叉搜索树的先序遍历序列,其中左右子树若为空则用0代替。
- 输出:
-
对应每个测试案例,
输出将二叉搜索树转换成排序的双向链表后,从链表头至链表尾的遍历结果。
- 样例输入:
1 2 1 0 0 3 0 0
- 样例输出:
1 2 3
解题思路:
这道题应该是最近写的最繁琐的一道题了。
首先输入按规则来,需要进行前序遍历输入
void createTree(BTree **b){ int m; scanf("%d",&m); if(m == 0) *b = NULL; else{ BTree *s = (BTree *)malloc(sizeof(BTree)); s->data = m; s->lchild = NULL; s->rchild = NULL; *b = s; createTree(&((*b)->lchild)); createTree(&((*b)->rchild)); } }
另外,整体的思路,是用一个指针记录转换的双链表表尾。
每次进行中序遍历的转换。
最先转换的是最左下的节点,
void converNode(BTree *b,BTree **p){ if(b == NULL) return ; BTree *pnow = b; if(b->lchild != NULL) converNode(b->lchild,p); pnow->lchild = *p; if(*p != NULL) (*p)->rchild = pnow; *p = pnow; if(b->rchild != NULL) converNode(b->rchild,p); }
每次遍历节点的左孩子右孩子。把左孩子指向转换链表的尾节点,并把末尾指针的右孩子指向自己。右孩子指向节点的右孩子。如果没有右孩子就返回。下面是代码思路的步骤:
1 找到最左边也就是最小的节点,PLast = NULL;
2 让节点的左孩子指向链尾,然后链尾指针右移。如果右孩子为空就返回。
最后我们从尾遍历回头指针返回。
全部代码:
#include <stdio.h> #include <stdlib.h> typedef struct btree{ int data; struct btree *lchild,*rchild; }BTree; void createTree(BTree **b); void inorderTree(BTree *b); BTree * convert(BTree *b); void converNode(BTree *b,BTree **p); int main(){ int n; scanf("%d",&n); while(n--){ BTree *b = (BTree *)malloc(sizeof(BTree)); createTree(&b); BTree *head = convert(b); while(head!=NULL){ printf("%d ",head->data); head = head->rchild; } printf("\n"); } return 0; } BTree* convert(BTree *b){ BTree *pLast = NULL; converNode(b,&pLast); BTree *phead = pLast; while(phead != NULL && phead->lchild != NULL) phead = phead->lchild; return phead; } void converNode(BTree *b,BTree **p){ if(b == NULL) return ; BTree *pnow = b; if(b->lchild != NULL) converNode(b->lchild,p); pnow->lchild = *p; if(*p != NULL) (*p)->rchild = pnow; *p = pnow; if(b->rchild != NULL) converNode(b->rchild,p); } void createTree(BTree **b){ int m; scanf("%d",&m); if(m == 0) *b = NULL; else{ BTree *s = (BTree *)malloc(sizeof(BTree)); s->data = m; s->lchild = NULL; s->rchild = NULL; *b = s; createTree(&((*b)->lchild)); createTree(&((*b)->rchild)); } } /************************************************************** Problem: 1503 User: xhalo Language: C Result: Accepted Time:80 ms Memory:1704 kb ****************************************************************/
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· 终于写完轮子一部分:tcp代理 了,记录一下
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理