题目:
输入一棵二元查找树,将该二元查找树转换成一个排序的双向链表。
要求不能创建任何新的结点,只调整指针的指向。
10
/ \
6 14
/ \ / \
4 8 12 16
转换成双向链表
4=6=8=10=12=14=16。
首先我们定义的二元查找树 节点的数据结构如下:
struct BSTreeNode
{
int m_nValue; // value of node
BSTreeNode *m_pLeft; // left child of node
BSTreeNode *m_pRight; // right child of node
};
/**
*
*/
package com.lhp;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
/**
1.把二元查找树转变成排序的双向链表
题目:
输入一棵二元查找树,将该二元查找树转换成一个排序的双向链表。
要求不能创建任何新的结点,只调整指针的指向。
10
/ \
6 14
/ \ / \
4 8 12 16
转换成双向链表
4=6=8=10=12=14=16。
首先我们定义的二元查找树 节点的数据结构如下:
struct BSTreeNode
{
int m_nValue; // value of node
BSTreeNode *m_pLeft; // left child of node
BSTreeNode *m_pRight; // right child of node
};
*/
/**
* 二元查找树
*/
class BSTree implements Cloneable,Serializable {
/**
* v0.8
*/
private static final long serialVersionUID = -7240326774488306261L;
private BSNode m_root; // 根节点
private BSNode tempListNode; // 创建doubleList的时候使用的临时变量
private BSNode tempListHead; // 创建doubleList的时候使用的临时变量
public void setM_root(BSNode mRoot) {
m_root = mRoot;
}
public BSNode getM_root() {
return m_root;
}
/**
* 深拷贝
*/
public Object clone() {
try {
// 没有去想树的节点拷贝算法,先用这种简便方法,再复杂的类型拷贝也不怕,不过所有相关类都必须是Serializable
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(baos);
oos.writeObject(this);
oos.close();
ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
ObjectInputStream ois = new ObjectInputStream(bais);
Object ob = ois.readObject();
ois.close();
return (BSTree) ob;
} catch (Exception e) {
System.out.println("CloneNotSupportedException: " + e);
e.printStackTrace();
}
return null;
}
/**
* 增加子节点
* @param 二元查找树节点
*/
public synchronized void addNode(BSNode node) {
if (null == this.m_root) {
this.m_root = node;
return;
}
BSNode tempNode = this.m_root;
while (true) {
if (node.getM_nValue() > tempNode.getM_nValue()) { // 大于父节点
if (null == tempNode.getM_pRight()) {
tempNode.setM_pRight(node);
return;
} else {
tempNode = tempNode.getM_pRight();
continue;
}
} else if (node.getM_nValue() < tempNode.getM_nValue()) { // 小于父节点
if (null == tempNode.getM_pLeft()) {
tempNode.setM_pLeft(node);
return;
} else {
tempNode = tempNode.getM_pLeft();
continue;
}
} else { // 等于父节点
return;
}
}
}
/**
* 生成双向链表
* @return 双向链表
* @throws CloneNotSupportedException
*/
public synchronized BSDoubleList changeToDoubleList() {
BSTree tempTree = (BSTree) this.clone(); // 临时树,替死鬼,被转换得面目全非,垃圾回收了吧...
// 其实改为changeTreeToDoubleList(this.getM_root());才符合题意,不过个人喜欢使用深拷贝,不破坏原来的树
if (null != tempTree) {
changeTreeToDoubleList(tempTree.getM_root());
}
BSDoubleList dlist = new BSDoubleList();
dlist.setHead(tempListHead);
return dlist;
}
private void changeTreeToDoubleList(BSNode node) {
if (null == node) {
return;
}
if (null != node.getM_pLeft()) {
changeTreeToDoubleList(node.getM_pLeft());
}
// -------------转换---------------
node.setM_pLeft(tempListNode);
if (null == tempListNode){
tempListHead = node;
} else {
tempListNode.setM_pRight(node);
}
//---------------------------------
tempListNode = node;
if (null != node.getM_pRight()) {
changeTreeToDoubleList(node.getM_pRight());
}
}
/**
* 打印中序遍历
*/
public synchronized void print() {
if (null == this.m_root) {
System.out.print("HashCode: " + this.hashCode() + "; 空树;");
return;
}
System.out.print("HashCode: " + this.hashCode() + "; 树: ");
print(this.m_root);
System.out.println();
}
private void print(BSNode node) {
if (null != node) {
print(node.getM_pLeft());
System.out.print(node.getM_nValue() + " ");
print(node.getM_pRight());
}
}
}
/**
* 二元查找树(双向链表)节点
*/
class BSNode implements Serializable {
/**
* v1.0
*/
private static final long serialVersionUID = 6136767364555910395L;
private int m_nValue; // 值
private BSNode m_pLeft; // 左(前驱)节点
private BSNode m_pRight; // 右(后继)节点
public BSNode(int value) {
this.m_nValue = value;
}
public int getM_nValue() {
return m_nValue;
}
public void setM_nValue(int mNValue) {
m_nValue = mNValue;
}
public BSNode getM_pLeft() {
return m_pLeft;
}
public void setM_pLeft(BSNode mPLeft) {
m_pLeft = mPLeft;
}
public BSNode getM_pRight() {
return m_pRight;
}
public void setM_pRight(BSNode mPRight) {
m_pRight = mPRight;
}
}
/**
* 双向链表
*/
class BSDoubleList {
private BSNode head; // 最左边的头结点
public BSNode getHead() {
return head;
}
public void setHead(BSNode head) {
this.head = head;
}
public synchronized void print() {
if (null != this.head) {
System.out.print("HashCode: " + this.hashCode() + "; 双向链表(正向): ");
while (true) {
if (null != this.head.getM_pRight()) {
System.out.print(this.head.getM_pRight().getM_nValue() + " ");
this.head = this.head.getM_pRight();
} else {
break;
}
}
System.out.println();
System.out.print("HashCode: " + this.hashCode() + "; 双向链表(逆向): ");
while (true) {
if (null != this.head) {
System.out.print(this.head.getM_nValue() + " ");
this.head = this.head.getM_pLeft();
} else {
break;
}
}
} else {
System.out.println("HashCode: " + this.hashCode() + "; 空链表;");
}
System.out.println();
}
}
public class One {
public static void main(String[] args) {
BSTree tree = new BSTree();
tree.addNode(new BSNode(10));
tree.addNode(new BSNode(6));
tree.addNode(new BSNode(14));
tree.addNode(new BSNode(4));
tree.addNode(new BSNode(8));
tree.addNode(new BSNode(12));
tree.addNode(new BSNode(16));
tree.print();
BSDoubleList dlist = tree.changeToDoubleList();
dlist.print();
System.out.println("原来的树:");
tree.print();
}
}