微软面试100题

最近在找工作,因为硕士期间的研究偏理论,国内对口公司较少。而自己想去的基本也都是软件公司,所以还是要抽出时间好好研究一下算法,争取在面试中取得一个好一点的成绩。


微软面试100题应该是经典中的经典,遂自己一边学习,一边将答案整理在这,帮助自己进步。


废话不多说,一题一题来吧。


1.把二元查找树转变成排序的双向链表

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

例如

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

首先我们定义的二元查找树节点的数据结构如下:

typedef struct NODE {
<span style="white-space:pre">	</span>int value;          // 节点alue
<span style="white-space:pre">	</span>NODE* left;  // 左子树
<span style="white-space:pre">	</span>NODE* right; // 右子树
} node_t;

题目中不需要考虑二元查找树的生成过程,但我还是权当复习,自行添加了二元查找树的生成函数。

/* 创建新节点 */
node_t* creatNode(int value)
{
	node_t* newNode = new node_t;
	if (!newNode) {
		cout << "memory allocation error" << endl;
		exit(1);
	}
	
	newNode->value = value;
	newNode->left = NULL;
	newNode->right = NULL;
	
	return newNode;
}

/* 递归生成二元查找数
void formTree(node_t** root, int value)
{
	if (!(*root)) {
		*root = creatNode(value);
		
		return;
	} else {
		if (value < (*root)->value) {
			formTree(&(*root)->left, value);
		} else {
			formTree(&(*root)->right, value);
		}
	}
}

此题可用递归来构建双向链表。基本思路为假设左子树能生成一个双向链表,此双向链表已将左子树的所有节点排序。右子树也能生成一个双向链表,此双向链表已将右子树的所有节点排序。因此只需将当前节点连接到左子树的双向链表末尾,并将右子树的双向链表链接在当前节点之后即可。代码如下:

/* 将二元查找树转换成双向链表 */
void sortTree(node_t* &head, node_t* node, node_t* &tail)
{		
	node_t* leftTail;
	node_t* rightHead;
	
	/* 递归生成左子树的双向链表 */
	if (node->left) {
		sortTree(head, node->left, leftTail);
	} 
	
	/* 递归生成右子树的双向链表 */
	if (node->right) {
		sortTree(rightHead, node->right, tail); 
	}
	
	/* 将当前节点连接在左子树双向链表的末尾 */
	if (!leftTail) {
		head = node;
	} else {
		leftTail->right = node;
		node->left = leftTail;
	}
	
	/* 将当前节点连接在右子树双向链表的开头 */
	if (!rightHead) {
		tail = node;
	} else {
		rightHead->left = node;
		node->right = rightHead;
	}
} 

/* 输入二元查找树 */
void printTree(node_t* root)
{
	if (!root){
		return;
	}
	
	printTree(root->left);
	cout << root->value << endl;
	printTree(root->right);
}

/* 输出生成的双向链表 */
void printChain(node_t* root)
{
	if (!root) {
		return;
	}
	
	cout << root->value << ",";
	printChain(root->right);
}

int main(int argc, const char* argb[])
{
	int in;
	int i;
	node_t* root = NULL;
	node_t* head = NULL;
	node_t* tail = NULL;
	
	int node[10] = {10, 8, 5, 15, 9, 13, 4, 2, 1, 25};
		
	for (i = 0; i < 10; i++) {
		formTree(&root, node[i]);
	}
	
	printTree(root);
	
	sortTree(head, root, tail);
	
	printChain(head);
	
	return 0;
}


 



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值