百度面试题

1)已知二叉树的先序遍历和中序遍历字符串,编程实现输出后序遍历字符串

eg:二叉树如下所示:

                 

                   a

              ↙   ↘

            b         c

         ↙↘        ↘

       d      e         g

前序:abdecg

中序:dbeacg

由前序的第一个a,可以把树分为两个部分,左子树和右子树。

在中序序列中找到a,左边部分则是左子树的中序,右边则是右子树的中序,

同样前序a的后面紧跟着左子树的前序和右子树的前序。

则问题可分解为两个结构相同的小问题。

1,先求左子树的后序;

2,求右子树的后序;

3,再将左子树和右子树的后序串起来,最后加上本身节点即可。

代码:

package com.xiejun;
public class Xulie {
		public static String postOrder(String preOrder,String centerOrder){
		if(preOrder.length()!=centerOrder.length()||preOrder.length()==1){
			return preOrder;
		}
		char root = preOrder.charAt(0);
		int index = centerOrder.indexOf(root);
		if(index==-1){
			throw new RuntimeException();
		}
		if(index==0){ //只有右子树
			String newPreOrder2 = preOrder.substring(1);
			String newCenterOrder2 = centerOrder.substring(1);
			return postOrder(newPreOrder2, newCenterOrder2)+root;
		}
		if(index==preOrder.length()-1){ //只有左子树
			String newPreOrder2 = preOrder.substring(1);
			String newCenterOrder2 = centerOrder.substring(0,preOrder.length()-1);
			return postOrder(newPreOrder2, newCenterOrder2)+root;
		}
		String newPreOrder1 = preOrder.substring(1, index+1);
		String newCenterOrder1 = centerOrder.substring(0, index);
		String newPreOrder2 = preOrder.substring(index+1, preOrder.length());
		String newCenterOrder2 = centerOrder.substring(index+1, preOrder.length());
		return postOrder(newPreOrder1, newCenterOrder1)+postOrder(newPreOrder2, newCenterOrder2)+root;
	}	
	public static void main(String[] args) {
		String postString = postOrder("abdecg","dbeacg");
		System.out.println(postString);
	}
}

2)如何终止一个线程

如何停止java的线程一直是一个困恼我们开发多线程程序的一个问题。这个问题最终在Java5的java.util.concurrent中得到了回答:使用interrupt(),让线程在run方法中停止。

在Sun公司的一篇文章《Why are Thread.stop, Thread.suspend and Thread.resume Deprecated? 》中详细讲解了舍弃这些方法的原因。那么,我们究竟应该如何停止线程呢?

1.当线程处于运行状态,可以设置volatile标志量来循环检测,让线程退出

2.处于可中断等待线程的停止

当线程处于下面的状况时,属于非运行状态:

  • 当sleep方法被调用。

  • 当wait方法被调用

当线程处于上述的状态时,使用前面介绍的方法就不可用了。这个时候,我们可以使用interrupt()来打破阻塞的情况

3. 处于IO阻塞状态线程的停止

Java中的输入输出流并没有类似于Interrupt的机制,但是JavaInterruptableChanel接口提供了这样的机制,任何实现了InterruptableChanel接口的类的IO阻塞都是可中断的,中断时抛出ClosedByInterruptedException,也是由Thread对象调用Interrupt方法完成中断调用。IO中断后将关闭通道。

        以文件IO为例,构造一个可中断的文件输入流的代码如下:

new InputStreamReader(  
           Channels.newInputStream(  
                   (new FileInputStream(FileDescriptor.in)).getChannel()))); 

  实现InterruptableChanel接口的类包括FileChannel,ServerSocketChannel, SocketChannel, Pipe.SinkChannel andPipe.SourceChannel,也就是说,原则上可以实现文件、Socket、管道的可中断IO阻塞操作。

        虽然解除IO阻塞的方法还可以直接调用IO对象的Close方法,这也会抛出IO异常。但是InterruptableChanel机制能够使处于IO阻塞的线程能够有一个和处于中断等待的线程一致的线程停止方案。

4.处于大数据IO读写中的线程停止

处于大数据IO读写中的线程实际上处于运行状态,而不是等待或阻塞状态,因此上面的interrupt机制不适用。线程处于IO读写中可以看成是线程运行中的一种特例。停止这样的线程的办法是强行closeio输入输出流对象,使其抛出异常,进而使线程停止。

        最好的建议是将大数据的IO读写操作放在循环中进行,这样可以在每次循环中都有线程停止的时机,这也就将问题转化为如何停止正在运行中的线程的问题了。

5. 在线程运行前停止线程

有时,线程中的run方法需要足够健壮以支持在线程实际运行前终止线程的情况。即在Thread创建后,到Threadstart方法调用前这段时间,调用自定义的stop方法也要奏效。从上述的停止处于等待状态线程的代码示例中,stop方法并不能终止运行前的线程,因为在Threadstart方法被调用前,调用interrupt方法并不会将Thread对象的中断状态置位,这样当run方法执行时,currentThreadisInterrupted方法返回false,线程将继续执行下去。

         为了解决这个问题,不得不自己再额外创建一个volatile标志量,并将其加入run方法的最开头:





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值