??xml version="1.0" encoding="utf-8" standalone="yes"?>四虎影视成人,国产亚洲精品美女久久久m,国产在线视频欧美一区二区三区http://www.aygfsteel.com/jiangshachina/category/38728.html同是Java爱好者,盔R何必曾相识Q?lt;br>    a cup of Java, cheers!zh-cnThu, 05 Jun 2014 10:23:55 GMTThu, 05 Jun 2014 10:23:55 GMT60树的汇??http://www.aygfsteel.com/jiangshachina/archive/2009/06/26/283467.htmlSha JiangSha JiangThu, 25 Jun 2009 23:11:00 GMThttp://www.aygfsteel.com/jiangshachina/archive/2009/06/26/283467.htmlhttp://www.aygfsteel.com/jiangshachina/comments/283467.htmlhttp://www.aygfsteel.com/jiangshachina/archive/2009/06/26/283467.html#Feedback0http://www.aygfsteel.com/jiangshachina/comments/commentRss/283467.htmlhttp://www.aygfsteel.com/jiangshachina/services/trackbacks/283467.html 树的汇?/span>
l上ơ浅谈了树的遍历之后Q这ơ再谈一下树的汇怅R?wbr>此处的汇L指将树中某个节点的数据按指定的规则汇集到它的父节点中?wbr>例如Q可以将树节点中的数值篏加到它的父节点中?wbr>仍如树的遍历一文,我将使用两种单的法Q递归与和q代Q?wbr>来实现这一功能?2009.08.09最后更?

1. 树节?/span>
仍然沿用树的遍历一文中的TreeNode/GenericTreeNodeQؓ便于阅读Q?wbr>GenericTreeNode中的若干关键属性展C如下,
public class GenericTreeNode<T> implements TreeNode {

    
private T userObject = null;

    
private TreeNode parent = null;

    
private List<GenericTreeNode<T>> children = new ArrayList<GenericTreeNode<T>>();

    
}

2. 递归?/span>
仍然先从最单的递归法开始,
public static Double recursiveGatherValue(GenericTreeNode<Double> node) {
    Double sumValue 
= null;
    
if (node.isLeaf()) {
        
return node.getUserObject();
    } 
else {
        sumValue 
= node.getUserObject();
        List
<GenericTreeNode<Double>> children = node.getChildren();
        
for (int i = 0, size = children.size(); i < size; i++) {
            Double bufGatherValue 
= recursiveGatherValue(children.get(i));
            sumValue 
+= bufGatherValue;
        }
    }

    node.setUserObject(sumValue);
    
return sumValue;
}
递归法还是一如既往的简单易懂。与递归遍历树相比,递归汇L的程序基本上没大的变化,我就不赘qC...

3. q代?/span>
与P代遍历树相比QP代汇L的程序有一些明昄变化?wbr>当初在思考P代法Ӟ有个问题一直困l着我:如何下U节点的Dl它的父节点Qƈ且父节点的D不断的进行篏加。在JavaWorld@TW中提个问题之?wbr>Q很快就得到?a >清晰的解{?/a>(真的很感谢社区里的大大们)?wbr>毫无疑问Q用q代法遍历一|旉要用一个栈Q但同时Qؓ了维护节点与汇dg间的关系Q?wbr>q需要另一个栈q行辅助。具体程序如下所C,
public static void iterativeGatherValue(GenericTreeNode<Double> node) {
    Stack
<NodeValueTuple<Double>> nodeValueStack = new Stack<NodeValueTuple<Double>>();
    Stack
<GenericTreeNode<Double>> nodeStack = new Stack<GenericTreeNode<Double>>();

    nodeStack.push(node);
    Double sumValue 
= new Double(0.0D);
    
while (!nodeStack.isEmpty()) {
        GenericTreeNode
<Double> bufNode = nodeStack.pop();
        
if (bufNode == null) {
            NodeValueTuple
<Double> bufNodeValueTuple = nodeValueStack.pop();
        bufNodeValueTuple.node.setUserObject(sumValue);

        sumValue += bufNodeValueTuple.value;
        } 
else if (bufNode.isLeaf()) {
            sumValue 
+= bufNode.getUserObject();
        } 
else {
            nodeValueStack.add(
new NodeValueTuple<Double>(bufNode, sumValue));

            sumValue 
= new Double(0.0D);
            nodeStack.push(
null);
            nodeStack.addAll(bufNode.getChildren());
        }
    }
}
在遍历树的过E中Q会某节点N与它的汇dg同置入一个栈(nodeValueStack)中,当节点N有子节点Ӟ则将它的子节点及其汇dg|入栈中Q节点N与它的子节点之间使用一个NULLD行分隔;如果节点N是叶节点则篏加汇d|如果节点N为NULLQ?wbr>则表C子节点们的汇dl束?br /> NodeValueTuple是一个二元组Q?wbr>用于l护节点与它的汇dg间的关系Q代码如下所C,
public class NodeValueTuple<V> {

    
public final GenericTreeNode<V> node;
    
public final V value;

    
public NodeValueTuple(GenericTreeNode<V> node, V value) {
        
this.node = node;
        
this.value = value;
    }
}
在上q的汇MQ均只篏加了叶节点中的数|而不分枝节点和根节Ҏ(gu)w所拥有的数倹{?wbr>如果要篏加这些节Ҏ(gu)w的数|应该如何做呢Q?wbr>大家自己做做看吧Q肯定非常简?^_^

4. 结
树的汇总肯定是一个十分常见的应用Q除了汇L据之外,我们q可以汇集节点中的对象,如汇L载在节点上的集合对象中的元素Q?wbr>使得父节点能够拥有所有子节点所拥有的元素。上q方法的效率应该不算低,主要是因为所有的树节点只需要访问一ơ?br />


Sha Jiang 2009-06-26 07:11 发表评论
]]>
树的遍历(?http://www.aygfsteel.com/jiangshachina/archive/2009/04/01/263241.htmlSha JiangSha JiangWed, 01 Apr 2009 12:40:00 GMThttp://www.aygfsteel.com/jiangshachina/archive/2009/04/01/263241.htmlhttp://www.aygfsteel.com/jiangshachina/comments/263241.htmlhttp://www.aygfsteel.com/jiangshachina/archive/2009/04/01/263241.html#Feedback4http://www.aygfsteel.com/jiangshachina/comments/commentRss/263241.htmlhttp://www.aygfsteel.com/jiangshachina/services/trackbacks/263241.html
树的遍历
之前的工作都没有接触到树Q也很研I它。幸q地的是Q在目前的工作中多次遇到树型l构的数据,那么讉K树节点中的数据就是必然的了,而且q需要按照指定规则对节点中的数据q行额外处理。经q学习之后,对与树相关的基本法有了一些认知,p划写几篇文。其实这L文章早已是汗牛充栋,而我只是把它当作我的学习ȝ|了Q以加深记忆与理解,如能对其他朋友有所助益Q则更感愉?zhn)?:-) (2009.04.03最后更?

q次先从最基础的开?-树的遍历。本文用了两种极常用的Ҏ(gu)来遍历树中的所有节?-递归QP代,但它们实现的都是深度优先(Depth-First)法?br />
1. 树节点与数据
先定义树节点及数?用户对象)Qƈ创徏试用的数据?br /> TreeNode是树节点的定义?br />
/**
 * 树节点的定义?br />  
*/
public interface TreeNode {

    
/**
     * 获取指定下标处的子节炏V?br />      * 
     * 
@param index
     *            下标?br />      * 
@return 子节炏V?br />      */
    
public TreeNode getChildAt(int index);

    
/**
     * q回指定子节点的下标?br />      * 
     * 
@param index
     *            下标?br />      * 
@return 子节炏V?br />      */
    
public int getChildIndex(TreeNode index);

    
/**
     * 获取子节点的数量?br />      * 
     * 
@return 子节点的数量?br />      */
    
public int getChildCount();

    
/**
     * q回父节炏V?br />      * 
     * 
@return 父节炏V?br />      */
    
public TreeNode getParent();

    
/**
     * 讄父节炏V注Q此处不需要改变父节点中的子节点元素?br />      * 
     * 
@param parent
     *            父节炏V?br />      
*/
    
public void setParent(TreeNode parent);

    
/**
     * 获取所有的子节炏V?br />      * 
     * 
@return 子节点的集合?br />      */
    
public List<?> getChildren();

    
/**
     * 是否为叶节点?br />      * 
     * 
@return 是叶节点Q返回trueQ否则,q回false?br />      */
    
public boolean isLeaf();
}

GenericTreeNode是一个通用的树节点实现?br />
public class GenericTreeNode<T> implements TreeNode {

    
private T userObject = null;

    
private TreeNode parent = null;

    
private List<GenericTreeNode<T>> children = new ArrayList<GenericTreeNode<T>>();

    
public GenericTreeNode(T userObject) {
        
this.userObject = userObject;
    }

    
public GenericTreeNode() {
        
this(null);
    }

    
/**
     * d子节炏V?br />      * 
     * 
@param child
     
*/
    
public void addChild(GenericTreeNode<T> child) {
        children.add(child);
        child.setParent(
this);
    }

    
/**
     * 删除指定的子节点?br />      * 
     * 
@param child
     *            子节炏V?br />      
*/
    
public void removeChild(TreeNode child) {
        removeChildAt(getChildIndex(child));
    }

    
/**
     * 删除指定下标处的子节炏V?br />      * 
     * 
@param index
     *            下标?br />      
*/
    
public void removeChildAt(int index) {
        TreeNode child 
= getChildAt(index);
        children.remove(index);
        child.setParent(
null);
    }

    
public TreeNode getChildAt(int index) {
        
return children.get(index);
    }

    
public int getChildCount() {
        
return children.size();
    }

    
public int getChildIndex(TreeNode child) {
        
return children.indexOf(child);
    }

    
public List<GenericTreeNode<T>> getChildren() {
        
return Collections.unmodifiableList(children);
    }

    
public void setParent(TreeNode parent) {
        
this.parent = parent;
    }

    
public TreeNode getParent() {
        
return parent;
    }

    
/**
     * 是否为根节点?br />      * 
     * 
@return 是根节点Q返回trueQ否则,q回false?br />      */
    
public boolean isRoot() {
        
return getParent() == null;
    }

    
public boolean isLeaf() {
        
return getChildCount() == 0;
    }

    
/**
     * 判断指定的节Ҏ(gu)否ؓ当前节点的子节点?br />      * 
     * 
@param node
     *            节点?br />      * 
@return 是当前节点的子节点,q回trueQ否则,q回false?br />      */
    
public boolean isChild(TreeNode node) {
        
boolean result;
        
if (node == null) {
            result 
= false;
        } 
else {
            
if (getChildCount() == 0) {
                result 
= false;
            } 
else {
                result 
= (node.getParent() == this);
            }
        }

        
return result;
    }

    
public T getUserObject() {
        
return userObject;
    }

    
public void setUserObject(T userObject) {
        
this.userObject = userObject;
    }

    @Override
    
public String toString() {
        
return userObject == null ? "" : userObject.toString();
    }
}

UserObject是节点上的用户对象,相当于是数据?br />
public class UserObject {

    
private String name = null;

    
private Integer value = Integer.valueOf(0);

    
public UserObject() {

    }

    
public UserObject(String code, Integer value) {
        
this.name = code;
        
this.value = value;
    }

    
public String getName() {
        
return name;
    }

    
public void setName(String code) {
        
this.name = code;
    }

    
public Integer getValue() {
        
return value;
    }

    
public void setValue(Integer value) {
        
this.value = value;
    }

    @Override
    
public String toString() {
        StringBuilder result 
= new StringBuilder();
        result.append(
"[name=").append(name).append(", value=").append(value).append("]");
        
return result.toString();
    }
}

TreeUtils是用于创建树的工L?br />
public class TreeUtils {

    
public static GenericTreeNode<UserObject> buildTree() {
        GenericTreeNode
<UserObject> root = new GenericTreeNode<UserObject>();
        root.setUserObject(
new UserObject("ROOT", Integer.valueOf(0)));

        GenericTreeNode
<UserObject> node1 = new GenericTreeNode<UserObject>();
        node1.setUserObject(
new UserObject("1", Integer.valueOf(0)));
        GenericTreeNode
<UserObject> node2 = new GenericTreeNode<UserObject>();
        node2.setUserObject(
new UserObject("2", Integer.valueOf(0)));
        GenericTreeNode
<UserObject> node3 = new GenericTreeNode<UserObject>();
        node3.setUserObject(
new UserObject("3", Integer.valueOf(5)));

        root.addChild(node1);
        root.addChild(node2);
        root.addChild(node3);

        GenericTreeNode
<UserObject> node11 = new GenericTreeNode<UserObject>();
        node11.setUserObject(
new UserObject("11", Integer.valueOf(0)));
        GenericTreeNode
<UserObject> node21 = new GenericTreeNode<UserObject>();
        node21.setUserObject(
new UserObject("21", Integer.valueOf(0)));

        node1.addChild(node11);
        node2.addChild(node21);

        GenericTreeNode
<UserObject> node111 = new GenericTreeNode<UserObject>();
        node111.setUserObject(
new UserObject("111", Integer.valueOf(3)));
        GenericTreeNode
<UserObject> node112 = new GenericTreeNode<UserObject>();
        node112.setUserObject(
new UserObject("112", Integer.valueOf(9)));
        GenericTreeNode
<UserObject> node211 = new GenericTreeNode<UserObject>();
        node211.setUserObject(
new UserObject("211", Integer.valueOf(6)));
        GenericTreeNode
<UserObject> node212 = new GenericTreeNode<UserObject>();
        node212.setUserObject(
new UserObject("212", Integer.valueOf(3)));

        node11.addChild(node111);
        node11.addChild(node112);
        node21.addChild(node211);
        node21.addChild(node212);

        
return root;
    }
}

2. 递归?/strong>
使用递归法的最大好处就?-单,但一般地Q我们都认ؓ递归的效率不高?br />
private static void recursiveTravel(GenericTreeNode<UserObject> node) {
    travelNode(node); 
// 讉K节点Q仅仅只是打印该节点|了?/span>
    List<GenericTreeNode<UserObject>> children = node.getChildren();
    
for (int i = 0; i < children.size(); i++) {
        recursiveTravel(children.get(i)); 
// 递归地访问当前节点的所有子节点?/span>
    }
}
大家肯定知道Q系l在执行递归Ҏ(gu)(对于其它Ҏ(gu)也是如此)时是使用q行时栈。对Ҏ(gu)的每一ơ调用,在栈中都会创Z份此ơ调用的zd记录--包括Ҏ(gu)的参敎ͼ局部变量,q回地址Q动态链接库Q返回值等?br /> 既然pȝ能够隐式C用栈L行递归Ҏ(gu)Q那么我们就可以昑ּC用栈来执行上q递归E序Q这也是递归E序转化P代程序的常用思想。下面的iterativeTravelҎ(gu)p用了q一思想?br />
3. q代?/strong>
private static void iterativeTravel(GenericTreeNode<UserObject> node) {
    Stack
<GenericTreeNode<UserObject>> nodes = new Stack<GenericTreeNode<UserObject>>();

    nodes.push(node); 
// 当前节点压入栈中?/span>
    while (!nodes.isEmpty()) {
        GenericTreeNode
<UserObject> bufNode = nodes.pop(); // 从栈中取Z个节炏V?/span>
        travelNode(bufNode); // 讉K节点?/span>
        if (!bufNode.isLeaf()) { // 如果该节点ؓ分枝节点Q则它的子节点全部加入栈中?/span>
            nodes.addAll(bufNode.getChildren());
        }
    }
}
与递归法相比,q代法的代码略多了几行,但仍然很单?br />
4. 结
׃上述两种Ҏ(gu)?隐式或显式地)使用了运行栈Q所以此处的q代法ƈ不能提高整个E序的效率。相反地Q由于在应用E序中显式地使用?java.util.Stack)QiterativeTravelҎ(gu)的效率可能反而更低。但iterativeTravel的最大好处是Q能够有效地避免q行时栈溢出(java.lang.StackOverflowError)?br /> 如果树的层次不太深,每层的子节点C太多Q那么用递归法应该是没有问题的。毕竟,z地E序会提供更多的好处?br />


Sha Jiang 2009-04-01 20:40 发表评论
]]>
判定一个点是否在三角Ş??http://www.aygfsteel.com/jiangshachina/archive/2008/07/24/217214.htmlSha JiangSha JiangThu, 24 Jul 2008 09:02:00 GMThttp://www.aygfsteel.com/jiangshachina/archive/2008/07/24/217214.htmlhttp://www.aygfsteel.com/jiangshachina/comments/217214.htmlhttp://www.aygfsteel.com/jiangshachina/archive/2008/07/24/217214.html#Feedback13http://www.aygfsteel.com/jiangshachina/comments/commentRss/217214.htmlhttp://www.aygfsteel.com/jiangshachina/services/trackbacks/217214.html判定一个点是否在三角Ş?/span>
如何判定一个点P是否存在于指定的三角形ABC内,q肯定是一个简单的问题Q本文仅用一个图形界面程序展CZ该问题,有兴的朋友可以看看?2008.07.24最后更?

在此处用一U常见且便的Ҏ(gu)Q?strong>如果三角形PABQPAC和PBC的面U之和与三角形ABC的面U相{,卛_判定点P在三角ŞABC?包括在三条边?
?br /> 可知Q该Ҏ(gu)的关键在于如何计三角Ş的面U。幸q地是,当知道三角Ş点(AQB和C)的坐?(Ax, Ay)Q?Bx, By)?Cx, Cy))之后Q即可计出光U:
= |(Ax * By + Bx * Cy + Cx * Zy - Ay * Bx - By * Cx - Cy * Ax) / 2|

关键的代码如下,
// q定的三个点的坐标,计算三角形面U?br /> // Point(java.awt.Point)代表点的坐标?/span>
private static double triangleArea(Point pos1, Point pos2, Point pos3) {
    
double result = Math.abs((pos1.x * pos2.y + pos2.x * pos3.y + pos3.x * pos1.y
            
- pos2.x * pos1.y - pos3.x * pos2.y - pos1.x * pos3.y) / 2.0D);
    
return result;
}

// 判断点pos是否在指定的三角形内?/span>
private static boolean inTriangle(Point pos, Point posA, Point posB,
        Point posC) {
    
double triangleArea = triangleArea(posA, posB, posC);
    
double area = triangleArea(pos, posA, posB);
    area 
+= triangleArea(pos, posA, posC);
    area 
+= triangleArea(pos, posB, posC);
    
double epsilon = 0.0001;  // ׃点数的计算存在着误差Q故指定一个够小的数Q用于判定两个面U是?q似)相等?/span>
    if (Math.abs(triangleArea - area) < epsilon) {
        
return true;
    }
    
return false;
}

执行该应用程序,用鼠标在其中点击三次Q即可绘制一个三角ŞQ如下组图所C:

然后仅需Ud鼠标Q就会出C个空心圆圈。如果圆圈的中心在三角内(包含在三条边?Q则圆圈昄为红Ԍ否则Q显CZؓ蓝色。如下组图所C:


完整代码如下Q?br />
public class CanvasPanel extends JPanel {

    
private static final long serialVersionUID = -6665936180725885346L;

    
private Point firstPoint = null;

    
private Point secondPoint = null;

    
private Point thirdPoint = null;

    
public CanvasPanel() {
        setBackground(Color.WHITE);
        addMouseListener(mouseAdapter);
        addMouseMotionListener(mouseAdapter);
    }

    
public void paintComponent(Graphics g) {
        
super.paintComponent(g);
        drawTriangel(g);
    }

    
private void drawTriangel(Graphics g) {
        
if (firstPoint != null && secondPoint != null) {
            g.drawLine(firstPoint.x, firstPoint.y, secondPoint.x, secondPoint.y);
            
if (thirdPoint != null) {
                g.drawLine(firstPoint.x, firstPoint.y, thirdPoint.x, thirdPoint.y);
                g.drawLine(secondPoint.x, secondPoint.y, thirdPoint.x, thirdPoint.y);
            }
        }
    }

    
private static boolean inTriangle(Point pos, Point posA, Point posB,
            Point posC) {
        
double triangeArea = triangleArea(posA, posB, posC);
        
double area = triangleArea(pos, posA, posB);
        area 
+= triangleArea(pos, posA, posC);
        area 
+= triangleArea(pos, posB, posC);
        
double epsilon = 0.0001;
        
if (Math.abs(triangeArea - area) < epsilon) {
            
return true;
        }
        
return false;
    }

    
private static double triangleArea(Point pos1, Point pos2, Point pos3) {
        
double result = Math.abs((pos1.x * pos2.y + pos2.x * pos3.y + pos3.x * pos1.y
                           
- pos2.x * pos1.y - pos3.x * pos2.y - pos1.x * pos3.y) / 2.0D);
        
return result;
    }

    
private MouseInputAdapter mouseAdapter = new MouseInputAdapter() {

        
public void mouseReleased(MouseEvent e) {
            Point pos 
= e.getPoint();
            
if (firstPoint == null) {
                firstPoint 
= pos;
            } 
else if (secondPoint == null) {
                secondPoint 
= pos;
                Graphics g 
= CanvasPanel.this.getGraphics();
                CanvasPanel.
this.paintComponent(g);
                g.drawLine(firstPoint.x, firstPoint.y, secondPoint.x, secondPoint.y);
            } 
else if (thirdPoint == null) {
                thirdPoint 
= pos;
                Graphics g 
= CanvasPanel.this.getGraphics();
                CanvasPanel.
this.paintComponent(g);
                g.drawLine(firstPoint.x, firstPoint.y, secondPoint.x, secondPoint.y);
                g.drawLine(firstPoint.x, firstPoint.y, thirdPoint.x, thirdPoint.y);
                g.drawLine(secondPoint.x, secondPoint.y, thirdPoint.x, thirdPoint.y);
            }
        }

        
public void mouseMoved(MouseEvent e) {
            Point pos 
= e.getPoint();
            Graphics2D g2 
= (Graphics2D) CanvasPanel.this.getGraphics();
            CanvasPanel.
this.paintComponent(g2);
            
if (firstPoint != null && secondPoint == null) {
                g2.drawLine(firstPoint.x, firstPoint.y, pos.x, pos.y);
            } 
else if (firstPoint != null && secondPoint != null && thirdPoint == null) {
                g2.drawLine(firstPoint.x, firstPoint.y, pos.x, pos.y);
                g2.drawLine(secondPoint.x, secondPoint.y, pos.x, pos.y);
            } 
else if (firstPoint != null && secondPoint != null && thirdPoint != null) {
                
if (inTriangle(pos, firstPoint, secondPoint, thirdPoint)) {
                    g2.setColor(Color.RED);
                } 
else {
                    g2.setColor(Color.BLUE);
                }
                
int radius = 4;
                g2.drawOval(pos.x 
- radius, pos.y - radius, radius * 2, radius * 2);
            }
        }
    };
}

public class Triangle extends JFrame {

    
private static final long serialVersionUID = 1L;

    
private CanvasPanel mainPanel = null;

    
public Triangle() {
        setTitle(
"Triangle");
        setSize(
new Dimension(300200));
        setResizable(
false);

        init();

        Container container 
= getContentPane();
        container.add(mainPanel);

        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setVisible(
true);
    }

    
private void init() {
        mainPanel 
= new CanvasPanel();
    }

    
public static void main(String[] args) {
        
new Triangle();
    }
}



Sha Jiang 2008-07-24 17:02 发表评论
]]>
վ֩ģ壺 | ³ƶ| | ض| | п| | | | | | | | ͷ| ƽ| Ϻӿ| μ| | | | | | ˮ| | | | | ¡| | | | | | Ѱ| | | «| Ѯ| տ| | ض|