二叉搜索树与双向链表
2016-05-14 15:40
239 查看
数据结构很多算法考察当中的树就是基于一定结构下增删改查或者搜索遍历的实践。
针对这个问题:
![](http://img.blog.csdn.net/20160514152818199)
什么是二叉搜索树,引用百科的图片:
![](http://img.blog.csdn.net/20160514152912674)
即是左边节点的值总是小于右边的值,当然也可以反过来。总之就是按一定的规则排序好的树形结构。要将它改变成双向链表。树的问题通常都可以通过递归去解决,这个问题一样有递归的解决方案,我采用了另一种思路来解决。
因为题目的要求是不能申请额外的空间,就是不能new新的节点对象。
我首先获取到所有节点的引用,这个可以采用任何你擅长的方式去遍历整个树。我采用的是我比较熟练的深度遍历的方法去获取整个树的引用。方法如下:
因为题目要求的是双向链表按照一定的顺序去排序,所以获取到所有引用,最好给这个引用排序,然后存放在一个有序的集合里。可以选择任何一种你擅长的排序方法去排序,我这里采用冒泡排序,方法如下:
这样我们就获取到了所有节点引用的有序列表。将这个函数进行封装。整个函数代码如下:
然后去遍历这个集合列表,分别修改每个节点的引用指向,这样就构建起来一个双向链表。
这里就完成了整个搜索二叉树对于双向链表的转换。
针对这个问题:
什么是二叉搜索树,引用百科的图片:
即是左边节点的值总是小于右边的值,当然也可以反过来。总之就是按一定的规则排序好的树形结构。要将它改变成双向链表。树的问题通常都可以通过递归去解决,这个问题一样有递归的解决方案,我采用了另一种思路来解决。
因为题目的要求是不能申请额外的空间,就是不能new新的节点对象。
我首先获取到所有节点的引用,这个可以采用任何你擅长的方式去遍历整个树。我采用的是我比较熟练的深度遍历的方法去获取整个树的引用。方法如下:
// 存放引用的集合 List<TreeNode> allTreeNodeList = new ArrayList<TreeNode>(); List<TreeNode> layerNodeList = new ArrayList<TreeNode>(); layerNodeList.add(treeNode); allTreeNodeList.add(treeNode); while (layerNodeList.size() != 0) { List<TreeNode> newLayerNodeList = new ArrayList<TreeNode>(); for (TreeNode node : layerNodeList) { if (node.left != null) { allTreeNodeList.add(node.left); newLayerNodeList.add(node.left); } if (node.right != null) { allTreeNodeList.add(node.right); newLayerNodeList.add(node.right); } } layerNodeList = newLayerNodeList; }
因为题目要求的是双向链表按照一定的顺序去排序,所以获取到所有引用,最好给这个引用排序,然后存放在一个有序的集合里。可以选择任何一种你擅长的排序方法去排序,我这里采用冒泡排序,方法如下:
// 进行排序 for(int i = 0;i < allTreeNodeList.size() - 1;i ++) { for(int j = 0;j < allTreeNodeList.size() - i - 1;j ++) { if(allTreeNodeList.get(j).val > allTreeNodeList.get(j + 1).val) { TreeNode tempNode = allTreeNodeList.get(j); allTreeNodeList.set(j, allTreeNodeList.get(j + 1)); allTreeNodeList.set(j + 1, tempNode); } } }
这样我们就获取到了所有节点引用的有序列表。将这个函数进行封装。整个函数代码如下:
// 排序好的节点引用
public static List<TreeNode> getTreeNodeList(TreeNode treeNode) {
if (treeNode == null)
return null;
// 存放引用的集合
List<TreeNode> allTreeNodeList = new ArrayList<TreeNode>();
List<TreeNode> layerNodeList = new ArrayList<TreeNode>();
layerNodeList.add(treeNode);
allTreeNodeList.add(treeNode);
while (layerNodeList.size() != 0) {
List<TreeNode> newLayerNodeList = new ArrayList<TreeNode>();
for (TreeNode node : layerNodeList) {
if (node.left != null) {
allTreeNodeList.add(node.left);
newLayerNodeList.add(node.left);
}
if (node.right != null) {
allTreeNodeList.add(node.right);
newLayerNodeList.add(node.right);
}
}
layerNodeList = newLayerNodeList;
}
// 进行排序 for(int i = 0;i < allTreeNodeList.size() - 1;i ++) { for(int j = 0;j < allTreeNodeList.size() - i - 1;j ++) { if(allTreeNodeList.get(j).val > allTreeNodeList.get(j + 1).val) { TreeNode tempNode = allTreeNodeList.get(j); allTreeNodeList.set(j, allTreeNodeList.get(j + 1)); allTreeNodeList.set(j + 1, tempNode); } } }
return allTreeNodeList;
}
然后去遍历这个集合列表,分别修改每个节点的引用指向,这样就构建起来一个双向链表。
public static TreeNode Convert(TreeNode pRootOfTree) { if(pRootOfTree == null) return null; List<TreeNode> allTreeNodeList = getTreeNodeList(pRootOfTree); for(int i = 0,size = allTreeNodeList.size();i < size - 1 ;i ++){ // 前一个 TreeNode font = allTreeNodeList.get(i); // 后一个 TreeNode after = allTreeNodeList.get(i + 1); font.right = after; after.left = font; // 最后一个节点的右指针(右孩子)指向null if(i + 1 == size) after.right = null; } for(TreeNode node : allTreeNodeList) { System.out.println(node.val); } return allTreeNodeList.get(0); }
这里就完成了整个搜索二叉树对于双向链表的转换。
相关文章推荐
- 41. First Missing Positive
- Ubuntu 12.10编译Android 4.0.3的常见错误
- HZAU 1005 Balance
- union
- Android 自定义checkbox样式
- c#-接口
- oracle输出信息
- 安卓绘制圆形图片
- 序列
- 剑指Offer:数值的整数次方
- android中加载本地图片到内存
- 微信html5开发平台
- Hibernate or Mybatis
- Android笔记hm002
- 欢迎使用CSDN-markdown编辑器
- query1.9radio checkbox操作
- 笔试面试题12--字符串拷贝、链接、比较无库函数实现
- 从 Qt 的 delete 说开来
- μCOS-Ⅲ——临界段
- μCOS-Ⅲ——临界段