1 问题

比如我们搜索二叉树如下,我们需要变成双向链表

2 分析

我们知道这个变成双向链接的时候是按照树的中序遍历打印的,我们只需要在中序遍历打印的时候操作该节点,我们可以用临时变量保存这个节点,同时我们也需要单独增加一个链表节点变量,我们需要保证这个节点的左边指向是该链表节点,然后该链表节点的右指向是这个节点,然后我们再把这个节点赋值给这个链表节点,就这样一直移动下去即可。

3 代码实现

我这里以下面的搜索二叉树进行操作的

42         61     3   5     7
#include <stdio.h>
#include <stdlib.h>typedef struct Tree
{int value;struct Tree* left;struct Tree* right;
} Tree;/** 把搜索二叉树转成双向链表,我们按照中序遍历*/
void convertNode(Tree* node, Tree** lastNodeList)
{if (node == NULL)return;Tree* pCurrent = node;if (pCurrent->left != NULL){convertNode(pCurrent->left, lastNodeList);}//这里就要进行我们每个节点的前后正确的指向了pCurrent->left = *lastNodeList;if (*lastNodeList != NULL){(*lastNodeList)->right = pCurrent;}*lastNodeList = pCurrent;if (pCurrent->right != NULL){convertNode(pCurrent->right, lastNodeList);}
}/** 把翻转好的双向链表尾巴节点移动到链表头*/
Tree* convert(Tree* node, Tree* lastNodeList)
{if (node == NULL || lastNodeList == NULL){printf("node is NULL or lastNodeList is NULL\n");return NULL;}Tree* last = NULL;convertNode(node, &lastNodeList);//因为这个时候lastNodeList已经到了双向链表尾巴,我们需要移动到链表头Tree* headNodeList = lastNodeList;while (headNodeList != NULL && headNodeList->left != NULL){headNodeList = headNodeList -> left;} return headNodeList;
}/** 双向链表从左到右打印*/
void printRightList(Tree* headNodeList)
{if (headNodeList == NULL){printf("headNodeList is NULL\n");return;}printf("we will print list from left to right\n");Tree* pCurrent = headNodeList;while (pCurrent != NULL){printf("value is %d\n", pCurrent->value);pCurrent = pCurrent->right;}
}/** 双向链表从右到左打印*/
void printLeftList(Tree* headNodeList)
{if (headNodeList == NULL){printf("headNodeList is NULL\n");return;}printf("we will print list from right to left\n");Tree* pCurrent = headNodeList;//先把链表头结点移动为链表的尾巴while (pCurrent->right != NULL){//printf("value is %d\n", pCurrent->value);pCurrent = pCurrent->right;}//pCurrent = pCurrent->left;while (pCurrent != NULL){printf("value is %d\n", pCurrent->value);pCurrent = pCurrent->left;}
}int main(void)
{Tree *node1 , *node2 , *node3, *node4, *node5, *node6, *node7;node1 = (Tree *)malloc(sizeof(Tree));node2 = (Tree *)malloc(sizeof(Tree));node3 = (Tree *)malloc(sizeof(Tree));node4 = (Tree *)malloc(sizeof(Tree));node5 = (Tree *)malloc(sizeof(Tree));node6 = (Tree *)malloc(sizeof(Tree));node7 = (Tree *)malloc(sizeof(Tree)); node1->value = 4;node2->value = 2;node3->value = 6;node4->value = 1;node5->value = 3;node6->value = 5;node7->value = 7;node1->left = node2;node1->right = node3;node2->left = node4;node2->right = node5;node3->left = node6;node3->right = node7;node4->left = NULL;node4->right = NULL;node5->left = NULL;node5->right = NULL;node6->left = NULL;node6->right = NULL;node7->left = NULL;node7->right = NULL;Tree* list = (Tree *)malloc(sizeof(Tree));if (!list){printf("malloc list fail\n");return -1;}Tree* firstNodeList = NULL;//convertNode(node1, &list);firstNodeList = convert(node1, list);if (firstNodeList == NULL){printf("firstNodeList is NULL\n");return -1;}printRightList(firstNodeList);printLeftList(firstNodeList);return 0;
}

4 运行结果

we will print list from left to right
value is 0
value is 1
value is 2
value is 3
value is 4
value is 5
value is 6
value is 7
we will print list from right to left
value is 7
value is 6
value is 5
value is 4
value is 3
value is 2
value is 1
value is 0

剑指offer之二叉搜索树和双向链表相关推荐

  1. 【LeetCode】剑指 Offer 36. 二叉搜索树与双向链表

    [LeetCode]剑指 Offer 36. 二叉搜索树与双向链表 文章目录 [LeetCode]剑指 Offer 36. 二叉搜索树与双向链表 package offer;//定义节点 class ...

  2. 【剑指offer】二叉搜索树转双向链表,C++实现

    原创博文,转载请注明出处! # 题目 输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的双向链表.要求不能创建任何新的结点,只能调整树中结点指针的指向. 二叉树节点的定义 struct TreeNod ...

  3. 【Java】 剑指offer(36) 二叉搜索树与双向链表

    本文参考自<剑指offer>一书,代码采用Java语言. 更多:<剑指Offer>Java实现合集   题目 输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的双向链表.要求不 ...

  4. 【LeetCode笔记】剑指 Offer 36. 二叉搜索树与双向链表(Java、二叉树、链表、原地算法)

    文章目录 题目描述 思路 && 代码 1. 非原地算法 2. 原地算法 二刷 题目描述 谈到二叉搜索树,那就得考虑考虑中序遍历啦- 这道题对中序遍历的理解提升很有好处! 思路 & ...

  5. [剑指offer] 36. 二叉搜索树与双向链表

    题目 输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的循环双向链表.要求不能创建任何新的节点,只能调整树中节点指针的指向. 需要返回双向链表最左侧的节点. 思路 1 排序链表:利用二叉搜索树的中序遍 ...

  6. 【算法】剑指 Offer 36. 二叉搜索树与双向链表

    1.概述 地址:https://leetcode-cn.com/problems/er-cha-sou-suo-shu-yu-shuang-xiang-lian-biao-lcof/ /* // De ...

  7. 2021-08-19剑指 Offer 36. 二叉搜索树与双向链表

    我的思路: 前序遍历保证链表的有序性,并且在这个遍历的同时调整指针的指向 class Solution {public:Node* treeToDoublyList(Node* root) {if(r ...

  8. 【LeetCode】剑指 Offer 33. 二叉搜索树的后序遍历序列

    [LeetCode]剑指 Offer 33. 二叉搜索树的后序遍历序列 文章目录 [LeetCode]剑指 Offer 33. 二叉搜索树的后序遍历序列 package offer;public cl ...

  9. 【LeetCode】剑指 Offer 54. 二叉搜索树的第k大节点

    [LeetCode]剑指 Offer 54. 二叉搜索树的第k大节点 文章目录 [LeetCode]剑指 Offer 54. 二叉搜索树的第k大节点 一.中序遍历(提前返回) 一.中序遍历(提前返回) ...

最新文章

  1. Windows下安装Zabbix agent
  2. 用平方映射理解tanh
  3. 好书推荐之《活着》 隐私策略(Privacy policy)
  4. SpringBoot使用Jsp
  5. 用CNN做NLP文本分类竞赛
  6. 为什么要用Redis?
  7. 问题随记 —— 无法打开包括文件: “dirent.h”: No such file or directory
  8. 浪曦 ASP.net AJAX系列 视频下载
  9. 数据处理第3部分:选择行的基本和高级的方法
  10. python爬新闻并保存csv_Python简单爬虫导出CSV文件的实例讲解
  11. 关于先有鸡还是先有蛋问题的科学的探讨
  12. DNA序列编码中Hairpin的定义和计算
  13. 百词斩和扇贝单词 背单词功能模块测试
  14. 华为笔记本没有网线口_有的笔记本电脑没有网线插口吗?
  15. MySql的存储过程的优点与缺点
  16. python中二进制和文本不同_关于Python字符编码与二进制不得不说的一些事
  17. 游戏超写实贴图制作技巧
  18. 如何将图片放大不失真,保持清晰度?
  19. pandas读取列数不同的数据方法
  20. 先进的分销管理系统(ADMS)行业调研报告 - 市场现状分析与发展前景预测

热门文章

  1. 通过Dapr实现一个简单的基于.net的微服务电商系统(七)——一步一步教你如何撸Dapr之服务限流...
  2. ASP.NET Core Filter如何支持依赖注入
  3. 如何在 ASP.Net Core 中使用 条件中间件
  4. WordPress 已过时?创始人与新架构拥护者开战
  5. 龙芯开源社区上线.NET主页
  6. IHostingEnvironment VS IHostEnvironment - .NET Core 3.0中的废弃类型
  7. Dapper介绍--Micro-ORM
  8. ASP.NET Core 中使用IHttpClientFactory发出HTTP请求
  9. 事关SuperSocket发布,寻找YangFan哥哥
  10. 使用Http-Repl工具测试ASP.NET Core 2.2中的Web Api项目