您的位置:首页 > 其它

二叉搜索树与双向链表

2016-05-14 15:40 239 查看
数据结构很多算法考察当中的树就是基于一定结构下增删改查或者搜索遍历的实践。

针对这个问题:



什么是二叉搜索树,引用百科的图片:



即是左边节点的值总是小于右边的值,当然也可以反过来。总之就是按一定的规则排序好的树形结构。要将它改变成双向链表。树的问题通常都可以通过递归去解决,这个问题一样有递归的解决方案,我采用了另一种思路来解决。

因为题目的要求是不能申请额外的空间,就是不能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);
}


这里就完成了整个搜索二叉树对于双向链表的转换。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: