Gitlib Gitlib
首页
  • 分类
  • 标签
  • 归档
  • Golang开发实践万字总结
  • MySQL核心知识汇总
  • Redis实践总结
  • MQ实践万字总结
  • Docker数据持久化总结
  • Docker网络模式深度解读
  • 常用游戏反外挂技术总结
  • 读书笔记
  • 心情杂货
  • 行业杂谈
  • 友情链接
关于我
GitHub (opens new window)

Ravior

以梦为马,莫负韶华
首页
  • 分类
  • 标签
  • 归档
  • Golang开发实践万字总结
  • MySQL核心知识汇总
  • Redis实践总结
  • MQ实践万字总结
  • Docker数据持久化总结
  • Docker网络模式深度解读
  • 常用游戏反外挂技术总结
  • 读书笔记
  • 心情杂货
  • 行业杂谈
  • 友情链接
关于我
GitHub (opens new window)
  • 操作系统

  • 计算机网络

  • 数据结构和算法

    • 数据结构

    • 算法

      • 常见排序算法实现
      • 常见搜索算法实现
      • Leetcode刷题之1.两数之和
      • 线性同余随机数算法实现
      • 深入理解递归算法
      • 二叉搜索树转双向链表
        • 题目描述
        • 解题思路
        • 代码实现
  • MySQL

  • Redis

  • Nginx

  • MongoDB

  • 其他

  • 计算机基础
  • 数据结构和算法
  • 算法
Ravior
2011-09-20
目录

二叉搜索树转双向链表

# 题目描述

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

# 解题思路

题目可能比较难理解,可以看如下的图,我们有一棵二叉搜索树,要求得右边的双向链表。

BST

在二叉搜索树中,左子结点的值总是小于父结点的值,右子节点的值总是大于父结点的值。因此我们在转换成排序双向链表时,原先指向左子结点的指针调整为链表中指向前一个结点的指针,原先指向右子节点的指针调整为链表中指向后一个结点的指针。由于要求链表是有序的,可以借助二叉树中序遍历,因为中序遍历算法的特点就是从小到大访问结点。当遍历访问到根结点时,假设根结点的左侧已经处理好,只需将根结点与上次访问的最近结点(左子树中最大值结点)的指针连接好即可。进而更新当前链表的最后一个结点指针。同时中序遍历过程正好是转换成链表的过程,可采用递归方法处理。

# 代码实现

/**
 * 双向链表节点
 */
class DLNode {
	public $data;
	public $next; // 指向下一个节点
	public $prev; // 指向前一个节点

	public function __construct($data) {
		$this->data = $data;
		$this->next = null;
		$this->prev = null;
	}
}

class DoubleLinkedList {
	private $head;

	public function append($data) {
		$node = new DLNode($data);
		if ($this->head == null) {
			$this->head = $node;
		} else {
			$this->appendNode($this->head, $node);
		}
	}

	private function appendNode($node, $newNode) {
		if ($node->next == null) {
			$node->next = $newNode;
			$newNode->prev = $node;
		} else {
			$this->appendNode($node->next, $newNode);
		}
	}

	public function toString() {
		$str = $this->head->data;
		$current = $this->head->next;

		while ($current) {
			$str .= ','.$current->data;
			$current = $current->next;
		}

		return $str;
	}
}

/**
* 将二叉搜索树转换成一个排序的双向链表
*/
public function convertDLinked() {
  $dlink = new DoubleLinkedList();
  $this->convertDLinkedNode($this->root, $dlink);
  return $dlink;
}

private function convertDLinkedNode($node, $dlink) {
  if ($node != null) {
    $this->convertDLinkedNode($node->left, $dlink);
    $dlink->append($node->data);
    $this->convertDLinkedNode($node->right, $dlink);
  }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
#算法#数据结构
上次更新: 2022/12/01, 11:09:34
深入理解递归算法
MySQL数据库安装及使用入门

← 深入理解递归算法 MySQL数据库安装及使用入门→

最近更新
01
常用游戏反外挂技术总结
11-27
02
Golang开发实践万字总结
11-11
03
Redis万字总结
10-30
更多文章>
Theme by Vdoing | Copyright © 2011-2022 Ravior | 粤ICP备17060229号-3 | MIT License
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式