您的位置:首页 > 职场人生

把二元查找树转变成排序的双向链表(微软面试)

2014-05-30 22:42 423 查看
把二元查找树转变成排序的双向链表

题目:

输入一棵二元查找树,将该二元查找树转换成一个排序的双向链表。

要求不能创建任何新的结点,只调整指针的指向。

10

/ \

6 14

/ \ / \

4 8 12 16

转换成双向链表

4=6=8=10=12=14=16。

思路:

建立一个head头节点(指向现在双向队列的头节点),一个tail尾节点(指向双向队列的尾节点)

中序遍历来更新和维护头节点与尾节点

遍历到的节点node时,

1,让该node的左节点指向tail尾节点

2, 若head=null时,则head=node

否则,将该节点加入到双向队列中,尾节点tail的右节点指向该节点node

3, 更新尾节点指向到该node

这里有两个版本一个Java,一个C++

我写了java版,C++版是从其他地方Copy的

因为java没有指针在操作节点时不太方便,本来采取递归的,当时由于java的值传递,操作时没有在外面更新。

最后采取中序遍历,每个节点操作,并维护头节点和尾节点。

有问题的话,麻烦读者指正。

java版

#Node.class

public class Node {

private Node left;
private Node right;
private int key;

public Node() {
}

public Node(int key) {
this.key = key;
}

public int getKey() {
return key;
}

public Node getLeft() {
return left;
}

public Node getRight() {
return right;
}

public void setKey(int key) {
this.key = key;
}

public void setLeft(Node left) {
this.left = left;
}

public void setRight(Node right) {
this.right = right;
}
}</span>


#BinaryTree.java

/**

* 输入一棵二元查找树,将该二元查找树转换成一个排序的双向链表。
 * 要求不能创建任何新的结点,只调整指针的指向。
 *         10
 *        /  \
 *        6  14
 *       / \ / \
 *      4  8 12 16
 *       
 *   转换成双向链表
 *   4<=>6<=>8<=>10<=>12<=>14<=>16。
 * 
 * @author heen
 *
 * @version 1.0 2014.5.30
 */
public class BinaryTree {

	private static Node root;
	private static int size;

	private static Node pHead = new Node();
	private static Node pTail = new Node();

	public BinaryTree(Node node) {
		this.root = node;
		size = 1;
	}

	/**
	 * Run configbation 输入数据 5 1 8 2 7
	 * */
	public static void main(String[] args) {
		int n = args.length;
		int[] inputArray = new int
;

		// 把输入的数据转化为int型的数组
		for (int i = 0; i < n; i++) {
			inputArray[i] = Integer.parseInt(args[i]);
			System.out.print(inputArray[i]);
		}
		System.out.println();

		// 二叉树增加节点
		for (int i = 0; i < n; i++) {
			Node node = new Node(inputArray[i]);
			addNode(node);
		}

		System.out.println("BinaryTree Size:" + size);
		System.out.println("***********二叉树中序遍历**************");

		// 中序调整节点,使二叉树调整为双向链表
		inorderAdjust(root);

		System.out.println("***********双向链表遍历**************");

		doubleLinkedList();
	}
	/**
	 * 双向链表遍历
	 */
	public static void doubleLinkedList() {
		while (pHead != null) {
			System.out.println("node:" + pHead.getKey());
			pHead = pHead.getRight();
		}
	}

	/**
	 * 中序遍历
	 * 
	 * @param node
	 */
	private static void inorderAdjust(Node node) {

		if (node == null)
			return;

		inorderAdjust(node.getLeft());
		convertToDoubleList(node);
		inorderAdjust(node.getRight());
	}

	/**
	 * 树转化为双向链表
	 * 
	 * 将中序遍历的节点加入到队尾,并调整队尾到新节点处
	 * 
	 * @param node
	 */
	private static void convertToDoubleList(Node node) {
		node.setLeft(pTail);

		if (pTail.getKey() != 0) {
			pTail.setRight(node);
		} else
			pHead = node;

		pTail = node;

		System.out.println("Node:" + node.getKey());
	}

	/**
	 * 增加节点,当root为null时,就把root赋值为该node
	 * 否则按规则加入二叉树
	 * @param node
	 */
	private static void addNode(Node node) {
		if (root == null){
			size++;
			root = node;
		}
			
		else
			addNode(root, node);
	}

	/**
	 * 按规则给二叉树增加节点
	 * 
	 * 右节点不小于所有左节点,
	 * 左节点不大于所有右节点
	 * 
	 * @param node
	 *  
	 */
	private static Node addNode(Node root, Node node) {

		if (root == null) {
			size++;
			return node;
		}

		if (node.getKey() >= root.getKey())

			root.setRight(addNode(root.getRight(), node));
		else
			root.setLeft(addNode(root.getLeft(), node));

		return root;
	}

}</span><span style="font-size:14px;">
</span>


执行结果:



C++版

#include <stdio.h>
#include <iostream.h>
struct BSTreeNode
{
int m_nValue; // value of node
BSTreeNode *m_pLeft; // left child of node
BSTreeNode *m_pRight; // right child of node
};
typedef BSTreeNode DoubleList;
DoubleList * pHead;
DoubleList * pListIndex;
void convertToDoubleList(BSTreeNode * pCurrent);
// 创建二元查找树
void addBSTreeNode(BSTreeNode * & pCurrent, int value)
{
if (NULL == pCurrent)
{
BSTreeNode * pBSTree = new BSTreeNode();
3
pBSTree->m_pLeft = NULL;
pBSTree->m_pRight = NULL;
pBSTree->m_nValue = value;
pCurrent = pBSTree;
}
else
{
if ((pCurrent->m_nValue) > value)
{
addBSTreeNode(pCurrent->m_pLeft, value);
}
else if ((pCurrent->m_nValue) < value)
{
addBSTreeNode(pCurrent->m_pRight, value);
}
else
{
//cout<<"重复加入节点"<<endl;
}
}
}
// 遍历二元查找树中序
void ergodicBSTree(BSTreeNode * pCurrent)
{
if (NULL == pCurrent)
{
return;
}
if (NULL != pCurrent->m_pLeft)
{
ergodicBSTree(pCurrent->m_pLeft);
}
// 节点接到链表尾部
convertToDoubleList(pCurrent);
// 右子树为空
if (NULL != pCurrent->m_pRight)
{
ergodicBSTree(pCurrent->m_pRight);
}
}
4
// 二叉树转换成list
void convertToDoubleList(BSTreeNode * pCurrent)
{
pCurrent->m_pLeft = pListIndex;
if (NULL != pListIndex)
{
pListIndex->m_pRight = pCurrent;
}
else
{
pHead = pCurrent;
}
pListIndex = pCurrent;
cout<<pCurrent->m_nValue<<endl;
}
int main()
{
BSTreeNode * pRoot = NULL;
pListIndex = NULL;
pHead = NULL;
addBSTreeNode(pRoot, 10);
addBSTreeNode(pRoot, 4);
addBSTreeNode(pRoot, 6);
addBSTreeNode(pRoot, 8);
addBSTreeNode(pRoot, 12);
addBSTreeNode(pRoot, 14);
addBSTreeNode(pRoot, 15);
addBSTreeNode(pRoot, 16);
ergodicBSTree(pRoot);
return 0;
}</span>


///////////////////////////////////////////////

4

6

8

10

12

14

15

16

Press any key to continue

//////////////////////////////////////////////
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐