看大神文章小结——微软面试1

大神 地址 :http://blog.csdn.net/v_JULY_v/article/details/6015165

1.把二元查找树转变成排序的双向链表
 题目:
输入一棵二元查找树,将该二元查找树转换成一个排序的双向链表。
要求不能创建任何新的结点,只调整指针的指向。
    
  10
  /    \
 6    14
 / \     / \
4 8 12 16
    /\

  7 9
 转换成双向链表
4=6=8=10=12=14=16。


上面是题目。 我尝试着 先想想思路。 要求是 不能创建任何借点 只能调整指针方向。 这是重点。刚开始想了一下。我暂时想到的思路是。因为是二元查找树。 本身就是有序的。左节点比他小。右节点比本身大。 转换的过程 就是一个有序查询的过程。 

需要分2种处理:(我的约定是: 将树左节点的指针 记录 链表的前节点。  右边节点的指针 记录 链表的后一个节点。)

1。如果本身是 父节点的左节点(图中6)。 那么 本身的左节点(4) 就是他转换成链表的前一个节点。  而右节点的最小左节点(7)。 就是它转换成链表的后一个节点;

就是将它本身的 父节点 的左节点指针 指向 他的右节点。

10

   / \
  8  14
  / \  / \
7 9 12 16

/

4

2..如果本身 是父节点的右节点。 跟上面的思路相反。就行了 右节点不变。左节点最大右节点 变 父节点的 右节点。

10

   / \
  8  14
  / \  \
7 9 12 

6  \

/ 16

4


这样 只要一次 顺序 排序 就可以实现了。 思路 这样 现在开始手写代码试试这思路 可不可行。 本人菜鸟 也只会java。 就用java实现;

经过一段时间的代码编写。总算实现了核心代码如下

	private void convert(Node root){
	
		if(root==null)
			return;
		convertLeft(root);
		convertRight(root);
	}
	private void convertLeft(Node root){
		Node leftNode =root.getPre();
		if(leftNode==null)
			return;
		Node rightNode=leftNode.getNext();
		if(rightNode!=null&&rightNode!=root){
			
			root.setPre(rightNode);
			Node childLeftNode=rightNode;
			while(childLeftNode.getPre()!=null){
				childLeftNode=childLeftNode.getPre();
			}
			childLeftNode.setPre(leftNode);
			leftNode.setNext(childLeftNode);
			convertLeft(root);
		}else{
			leftNode.setNext(root);
			convertLeft(leftNode);
		}		
	}
	private void convertRight(Node root){
		Node rightNode = root.getNext();
		if(rightNode==null)
			return;
		Node leftNode=rightNode.getPre();
		if(leftNode!=null&&leftNode!=root){
			
			root.setNext(leftNode);
			Node childRightNode=leftNode;
			while(childRightNode.getNext()!=null){
				childRightNode=childRightNode.getNext();
			}
			childRightNode.setNext(rightNode);
			rightNode.setPre(childRightNode);
			convertRight(root);
		}else{
			rightNode.setPre(root);
			convertRight(rightNode);
		}
		
	}	

运行测试了一下 貌似可以的。测试一下 超过一万个时候 直接就 java.lang.StackOverflowError。。 递归的烦恼啊。

然后思考了一下。貌似就是一个中序查询啊。不管怎么说 是完成。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值