[程序员面试题精选100题(01)]-二叉查找树转成排序的双向链表

题目来自网络,声称这是一道微软的面试题。

先来看看题目:

输入一棵二叉查找树,将该二叉查找树转换成一个排序的双向链表。
要求不能创建任何新的结点,只调整指针的指向。

比如将二叉查找树
        10
       /    \
  6          14
  /  \       /  \

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

仔细分析一下,这并不是一道难题。

回忆一下二叉查找树(binary search tree),如果采用中序遍历,就可以得到有序的遍历结果。

于是,选用递归类似中序遍历的方式来解决这个问题

(1)左子树转化成排序的双向链表

(2)左子树的最后一个结点与根结点双向链接

(3)右子树转化成排序的双向链表

(4)根节点与右子树的第一个结点双向链接

代码如下:

#include <stdlib.h>
#include <stdio.h>

typedef struct SNode{
	SNode* left;
	SNode* right;
	int value;
	SNode(int v_):left(NULL),right(NULL){value = v_; }
}Node;

Node* convert_2_double_link_list(Node * root)
{
	if (!root) return NULL;
	Node* pre = convert_2_double_link_list(root->left);
	if (pre) {
		//find the end of list
		Node* p = pre;
		while(p->right != NULL) {
			p = p->right;
		}
		root->left = p;
		p->right = root;
	} else {
		pre = root;
		root->left = NULL;
	}
	Node * post = convert_2_double_link_list(root->right);
	
	if (post) {
		post->left = root;
		root->right = post;
	} else {
		root->right = NULL;
	}
	return pre;
}

void visit(Node* p)
{
	while (p){
		printf("%d->\n",p->value);
		p = p->right;
	}

}
int main()
{
	Node * root = new Node(10);
	Node * r11 = new Node(6);
	root->left = r11;
	Node * r12 = new Node(14);
	root->right = r12;
	Node * r21 = new Node(4);
	r11->left = r21;
	Node * r22 = new Node(8);
	r11->right = r22;

	Node * r31 = new Node(12);
	r12->left = r31;
	Node * r32 = new Node(16);
	r12->right = r32;

	Node* p = convert_2_double_link_list(root);
	visit(p);
	//system("pause");
	return 0;
}

解答完毕之后看到这篇文章的解法

http://blog.csdn.net/sjf0115/article/details/7707647

这个blog中提到了2种不同的实现方法,甚好:

(1)第一种与本文中的方法相似,不过文中,标记了是左子还是右子,来决定最后返回部分排序好的头节点还是尾节点。

(2)第二种方式,就是直接采取中序遍历,用一个指向双向链表队尾的指针记录中序遍历访问的节点。


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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值