Job Hunting 之路——算法题(一)

2 篇文章 0 订阅
1 篇文章 0 订阅

        早就在CSDN的网摘上看到《[置顶]横空出世,席卷互联网--评微软等公司数据结构和算法面试100题》这篇文章,想着找工作联系算法的时候一定好好看看。终于看完了数据结构的基础之后,挤出一些时间来,做做这些题目,感受一下大公司笔面的算法题。其实自己算法方便一直比较薄弱,所以只是尝试一下吧。

        接触的第一门语言是C++,但是上研之后,实验室一直用Java,也就基本没怎么用C++,导致现在对C++越来越生疏。对于这种算法题目,我也是用Java实现的。自我感觉对Java还是比较熟悉的,尤其Eclipse开发环境非常方便啊。把我写的实现贴出来,不知道会不会有人看啊


第一道题:

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
};

对于这道题,我首先采用二元查找树的中序遍历的非递归实现方法实现了一遍,虽然没有创建任何其他结点,但是我使用了栈。

然后参考了提供的答案中的思想,采用二院搜索树的递归实现来做,这样确实不需要多余的存储空间,只需要多加几个指针(Java中是引用)即可。

package test.interview.algorithm;

import java.util.Stack;

public class Problem1 {

	/**
	 * 1. 把二元查找树转变成排序的双向链表
	 * 题目:
	 * 输入一棵二元查找树,将该二元查找树转换成一个排序的双向链表。
	 * 要求不能创建任何新的结点,只调整指针的指向。
	 * 
	 * @ZJ思路:二元查找树的中序遍历就是排序序列,修改指针的指向,即可得到有序双向表
	 * 
	 * @param args
	 */
	
	static DoubleList list = new DoubleList();
	
	public static void main(String[] args) {
		// TODO Auto-generated method stub
                // 用非常简单的方法构建一棵二叉树
                int[] a = {10,6,14,4,8,12,16};
		BSTreeNode node4 = new BSTreeNode(4,null,null);
		BSTreeNode node8 = new BSTreeNode(8,null,null);
		BSTreeNode node6 = new BSTreeNode(6,node4,node8);
		
		BSTreeNode node12 = new BSTreeNode(12,null,null);
		BSTreeNode node16 = new BSTreeNode(16,null,null);
		BSTreeNode node14 = new BSTreeNode(14,node12,node16);
		
		BSTreeNode node10 = new BSTreeNode(10,node6,node14);
			
		BSTreeNode node;
                // 这是用非递归中序遍历的方法实现的
//		node = BinaryTreeToDoubleList(node10);
//		
//		for(;node!=null;node=node.m_pLeft){
//			System.out.print(node.m_nValue+",");
//		}
		// 采用递归的中序遍历实现的
		inorderTranvers(node10);
		node = list.head;
		for(;node!=null;node=node.m_pRight){
			System.out.print(node.m_nValue+",");
		}
		
	}
	// 采用中序遍历的非递归实现,使用了栈,不知道可不可以
	public static BSTreeNode BinaryTreeToDoubleList(BSTreeNode root){
		Stack<BSTreeNode> s = new Stack<BSTreeNode>();
		BSTreeNode node = root; // 记录当前结点
		BSTreeNode prev = null; // 记录当前结点的前一个结点,初始化为null,便于后面判断
		
		while(node!=null||!s.isEmpty()){
			if(node!=null){
				s.push(node);
				node = node.m_pLeft;
			}
			else{
				node = s.pop();
				if(prev==null){					
					prev = node;
				}else{
					prev.m_pRight = node;
					node.m_pLeft = prev;
					prev = node;
				}
								
				node=node.m_pRight; 
			}
		}
		return prev;
	}
	
	/**
	 * 答案中的思想,采用中序遍历递归实现,没有采用多余的存储空间
	 * 采用了全局变量双链表,其实还是比较容易的,很多东西只要敢想,就能做出来!!!
	 * 
	 * @param root
	 * @return
	 */	
	public static void inorderTranvers(BSTreeNode node){
		
		if(node!=null){
			inorderTranvers(node.m_pLeft);
			
			addToDoubleList(node);
			
			inorderTranvers(node.m_pRight);
		}
		
	}
	
	private static void addToDoubleList(BSTreeNode node){
		// 这里使用current指针指向上一次的当前结点,其实就充当了前一个结点的角色
		
		if(list.head==null){ // 第一次调用函数,那么双向链表的头为空,
			list.head = node;
			list.current = node;
		}else{
			list.current.m_pRight = node;
			node.m_pLeft = list.current;
			list.current = node;
		}
	}
	
}

class DoubleList{
	
	BSTreeNode head;
	BSTreeNode current;
	BSTreeNode tail;
}

class BSTreeNode
{
	public BSTreeNode(int value,BSTreeNode left,BSTreeNode right){
		m_nValue = value;
		m_pLeft = left;
		m_pRight = right;
	}
	int m_nValue; // value of node
	BSTreeNode m_pLeft; // left child of node
	BSTreeNode m_pRight; // right child of node
};


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值