import java.util.ArrayList;
從網(wǎng)站建設(shè)到定制行業(yè)解決方案,為提供網(wǎng)站設(shè)計(jì)、成都做網(wǎng)站服務(wù)體系,各種行業(yè)企業(yè)客戶提供網(wǎng)站建設(shè)解決方案,助力業(yè)務(wù)快速發(fā)展。創(chuàng)新互聯(lián)將不斷加快創(chuàng)新步伐,提供優(yōu)質(zhì)的建站服務(wù)。
// 樹(shù)的一個(gè)節(jié)點(diǎn)
class TreeNode {
Object _value = null; // 他的值
TreeNode _parent = null; // 他的父節(jié)點(diǎn),根節(jié)點(diǎn)沒(méi)有PARENT
ArrayList _childList = new ArrayList(); // 他的孩子節(jié)點(diǎn)
public TreeNode( Object value, TreeNode parent ){
this._parent = parent;
this._value = value;
}
public TreeNode getParent(){
return _parent;
}
public String toString() {
return _value.toString();
}
}
public class Tree {
// 給出寬度優(yōu)先遍歷的值數(shù)組,構(gòu)建出一棵多叉樹(shù)
// null 值表示一個(gè)層次的結(jié)束
// "|" 表示一個(gè)層次中一個(gè)父親節(jié)點(diǎn)的孩子輸入結(jié)束
// 如:給定下面的值數(shù)組:
// { "root", null, "left", "right", null }
// 則構(gòu)建出一個(gè)根節(jié)點(diǎn),帶有兩個(gè)孩子("left","right")的樹(shù)
public Tree( Object[] values ){
// 創(chuàng)建根
_root = new TreeNode( values[0], null );
// 創(chuàng)建下面的子節(jié)點(diǎn)
TreeNode currentParent = _root; // 用于待創(chuàng)建節(jié)點(diǎn)的父親
//TreeNode nextParent = null;
int currentChildIndex = 0; // 表示 currentParent 是他的父親的第幾個(gè)兒子
//TreeNode lastNode = null; // 最后一個(gè)創(chuàng)建出來(lái)的TreeNode,用于找到他的父親
for ( int i = 2; i values.length; i++ ){
// 如果null ,表示下一個(gè)節(jié)點(diǎn)的父親是當(dāng)前節(jié)點(diǎn)的父親的第一個(gè)孩子節(jié)點(diǎn)
if ( values[i] == null ){
currentParent = (TreeNode)currentParent._childList.get(0);
currentChildIndex = 0;
continue;
}
// 表示一個(gè)父節(jié)點(diǎn)的所有孩子輸入完畢
if ( values[i].equals("|") ){
if ( currentChildIndex+1 currentParent._childList.size() ){
currentChildIndex++;
currentParent = (TreeNode)currentParent._parent._childList.get(currentChildIndex);
}
continue;
}
TreeNode child = createChildNode( currentParent, values[i] );
}
}
TreeNode _root = null;
public TreeNode getRoot(){
return _root;
}
/**
// 按寬度優(yōu)先遍歷,打印出parent子樹(shù)所有的節(jié)點(diǎn)
private void printSteps( TreeNode parent, int currentDepth ){
for ( int i = 0; i parent._childList.size(); i++ ){
TreeNode child = (TreeNode)parent._childList.get(i);
System.out.println(currentDepth+":"+child);
}
if ( parent._childList.size() != 0 ) System.out.println(""+null);// 為了避免葉子節(jié)點(diǎn)也會(huì)打印null
//打印 parent 同層的節(jié)點(diǎn)的孩子
if ( parent._parent != null ){ // 不是root
int i = 1;
while ( i parent._parent._childList.size() ){// parent 的父親還有孩子
TreeNode current = (TreeNode)parent._parent._childList.get(i);
printSteps( current, currentDepth );
i++;
}
}
// 遞歸調(diào)用,打印所有節(jié)點(diǎn)
for ( int i = 0; i parent._childList.size(); i++ ){
TreeNode child = (TreeNode)parent._childList.get(i);
printSteps( child, currentDepth+1 );
}
}
// 按寬度優(yōu)先遍歷,打印出parent子樹(shù)所有的節(jié)點(diǎn)
public void printSteps(){
System.out.println(""+_root);
System.out.println(""+null);
printSteps(_root, 1 );
}**/
// 將給定的值做為 parent 的孩子,構(gòu)建節(jié)點(diǎn)
private TreeNode createChildNode( TreeNode parent, Object value ){
TreeNode child = new TreeNode( value , parent );
parent._childList.add( child );
return child;
}
public static void main(String[] args) {
Tree tree = new Tree( new Object[]{ "root", null,
"left", "right", null,
"l1","l2","l3", "|", "r1","r2",null } );
//tree.printSteps();
System.out.println(""+ ( (TreeNode)tree.getRoot()._childList.get(0) )._childList.get(0) );
System.out.println(""+ ( (TreeNode)tree.getRoot()._childList.get(0) )._childList.get(1) );
System.out.println(""+ ( (TreeNode)tree.getRoot()._childList.get(0) )._childList.get(2) );
System.out.println(""+ ( (TreeNode)tree.getRoot()._childList.get(1) )._childList.get(0) );
System.out.println(""+ ( (TreeNode)tree.getRoot()._childList.get(1) )._childList.get(1) );
}
}
java:二叉樹(shù)添加和查詢方法
package arrays.myArray;
public class BinaryTree {
private Node root;
// 添加數(shù)據(jù)
public void add(int data) {
// 遞歸調(diào)用
if (null == root)
root = new Node(data, null, null);
else
addTree(root, data);
}
private void addTree(Node rootNode, int data) {
// 添加到左邊
if (rootNode.data data) {
if (rootNode.left == null)
rootNode.left = new Node(data, null, null);
else
addTree(rootNode.left, data);
} else {
// 添加到右邊
if (rootNode.right == null)
rootNode.right = new Node(data, null, null);
else
addTree(rootNode.right, data);
}
}
// 查詢數(shù)據(jù)
public void show() {
showTree(root);
}
private void showTree(Node node) {
if (node.left != null) {
showTree(node.left);
}
System.out.println(node.data);
if (node.right != null) {
showTree(node.right);
}
}
}
class Node {
int data;
Node left;
Node right;
public Node(int data, Node left, Node right) {
this.data = data;
this.left = left;
this.right = right;
}
}
你好,遞歸調(diào)用簡(jiǎn)單的說(shuō)就是自己無(wú)限的調(diào)用自己的下一級(jí),也就是說(shuō)父節(jié)點(diǎn)和子節(jié)點(diǎn)擁有相同的屬性和方法,所以在處理玩當(dāng)前節(jié)點(diǎn)也就是父節(jié)點(diǎn)的時(shí)候,就調(diào)用處理自身下面的子節(jié)點(diǎn),類似于文件夾和文件,文件夾相對(duì)于當(dāng)前目錄來(lái)說(shuō)是父節(jié)點(diǎn),而他里面的子文件夾就相當(dāng)于子節(jié)點(diǎn),但是處理子文件夾的時(shí)候,子文件夾就成了父節(jié)點(diǎn),一次遞歸處理完畢
希望可以幫助到你
//先選中節(jié)點(diǎn)才能增加節(jié)點(diǎn)
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.tree.*;
public class TreeTest implements ActionListener,TreeModelListener{
JLabel label=null;
JTree tree=null;
DefaultTreeModel treeModel=null;
String nodeName=null;//原有節(jié)點(diǎn)名稱
public TreeTest(){
JFrame f=new JFrame("TreeTest");
Container contentPane=f.getContentPane();
DefaultMutableTreeNode root=new DefaultMutableTreeNode("資源管理器");
tree=new JTree(root);
tree.setEditable(true);
tree.addMouseListener(new MouseHandle());
treeModel=(DefaultTreeModel)tree.getModel();
treeModel.addTreeModelListener(this);
JScrollPane scrollPane=new JScrollPane();
scrollPane.setViewportView(tree);
JPanel panel=new JPanel();
JButton b=new JButton("新增節(jié)點(diǎn)");
b.addActionListener(this);
panel.add(b);
b=new JButton("刪除節(jié)點(diǎn)");
b.addActionListener(this);
panel.add(b);
b=new JButton("清除所有節(jié)點(diǎn)");
b.addActionListener(this);
panel.add(b);
label=new JLabel("Action");
contentPane.add(panel,BorderLayout.NORTH);
contentPane.add(scrollPane,BorderLayout.CENTER);
contentPane.add(label,BorderLayout.SOUTH);
f.pack();
f.setVisible(true);
f.addWindowListener(new WindowAdapter(){
public void windowClosing(WindowEvent e){
System.exit(0);
}
});
}
//本方法運(yùn)行新增、刪除、清除所有節(jié)點(diǎn)的程序代碼.
public void actionPerformed(ActionEvent ae){
if (ae.getActionCommand().equals("新增節(jié)點(diǎn)")){
DefaultMutableTreeNode parentNode=null;
DefaultMutableTreeNode newNode=new DefaultMutableTreeNode("新節(jié)點(diǎn)");
newNode.setAllowsChildren(true);
TreePath parentPath=tree.getSelectionPath();
//取得新節(jié)點(diǎn)的父節(jié)點(diǎn)
parentNode=(DefaultMutableTreeNode)(parentPath.getLastPathComponent());
//由DefaultTreeModel的insertNodeInto()方法增加新節(jié)點(diǎn)
treeModel.insertNodeInto(newNode,parentNode,parentNode.getChildCount());
//tree的scrollPathToVisible()方法在使Tree會(huì)自動(dòng)展開(kāi)文件夾以便顯示所加入的新節(jié)點(diǎn)。若沒(méi)加這行則加入的新節(jié)點(diǎn)
//會(huì)被 包在文件夾中,你必須自行展開(kāi)文件夾才看得到。
tree.scrollPathToVisible(new TreePath(newNode.getPath()));
label.setText("新增節(jié)點(diǎn)成功");
}
if (ae.getActionCommand().equals("刪除節(jié)點(diǎn)")){
TreePath treepath=tree.getSelectionPath();
if (treepath!=null){
//下面兩行取得選取節(jié)點(diǎn)的父節(jié)點(diǎn).
DefaultMutableTreeNode selectionNode=(DefaultMutableTreeNode)treepath.getLastPathComponent();
TreeNode parent=(TreeNode)selectionNode.getParent();
if (parent!=null) {
//由DefaultTreeModel的removeNodeFromParent()方法刪除節(jié)點(diǎn),包含它的子節(jié)點(diǎn)。
treeModel.removeNodeFromParent(selectionNode);
label.setText("刪除節(jié)點(diǎn)成功");
}
}
}
if (ae.getActionCommand().equals("清除所有節(jié)點(diǎn)")){
//下面一行,由DefaultTreeModel的getRoot()方法取得根節(jié)點(diǎn).
DefaultMutableTreeNode rootNode=(DefaultMutableTreeNode)treeModel.getRoot();
//下面一行刪除所有子節(jié)點(diǎn).
rootNode.removeAllChildren();
//刪除完后務(wù)必運(yùn)行DefaultTreeModel的reload()操作,整個(gè)Tree的節(jié)點(diǎn)才會(huì)真正被刪除.
treeModel.reload();
label.setText("清除所有節(jié)點(diǎn)成功");
}
}
public void treeNodesChanged(TreeModelEvent e){
TreePath treePath=e.getTreePath();
DefaultMutableTreeNode node=(DefaultMutableTreeNode)treePath.getLastPathComponent();
try{
int[] index=e.getChildIndices();
node=(DefaultMutableTreeNode)node.getChildAt(index[0]);
}catch(NullPointerException exc){}
label.setText(nodeName+"更改數(shù)據(jù)為:"+(String)node.getUserObject());
}
public void treeNodesInserted(TreeModelEvent e){
System.out.println("new node insered");
}
public void treeNodesRemoved(TreeModelEvent e){
System.out.println("node deleted");
}
public void treeStructureChanged(TreeModelEvent e){
System.out.println("Structrue changed");
}
public static void main(String[] args){
new TreeTest();
}
class MouseHandle extends MouseAdapter{
public void mousePressed(MouseEvent e){
try{
JTree tree=(JTree)e.getSource();
int rowLocation=tree.getRowForLocation(e.getX(),e.getY());
TreePath treepath=tree.getPathForRow(rowLocation);
TreeNode treenode=(TreeNode)treepath.getLastPathComponent();
nodeName=treenode.toString();
}catch(NullPointerException ne){}
}
}
}
我看了一下,知道lz的錯(cuò)誤在哪了。
createbintree方法中。以lz的講的先輸入a、再輸入三回車,也就是當(dāng)前只有一個(gè)節(jié)點(diǎn)a。下面就以樓主的數(shù)據(jù)來(lái)講一下函數(shù)所走流程
1.可是當(dāng)樓主輸入a之后,按完第一個(gè)回車
當(dāng)前取得的數(shù)據(jù)a,走else分支,接下來(lái)就到myTree.data = str;//為節(jié)點(diǎn)賦值,假設(shè)為父節(jié)點(diǎn)1
myTree.lchild = new BintNode();//為myTree建立了左節(jié)點(diǎn)
createbintree(myTree.lchild);
//遞歸調(diào)用跳到2
myTree.rchild = new BintNode();//創(chuàng)建右節(jié)點(diǎn)
createbintree(myTree.rchild);
//遞歸調(diào)用跳到3
2.輸入第二個(gè)回車,數(shù)據(jù)為空,那么走if分支,myTree=null,照理說(shuō)應(yīng)該將myTree該節(jié)點(diǎn)賦值為空,也就代表沒(méi)有該節(jié)點(diǎn)。
其實(shí)這個(gè)想法是錯(cuò)誤的。在1中,為父節(jié)點(diǎn)1分配了左孩子,已經(jīng)是new出來(lái)的對(duì)象。不知道lz對(duì)函數(shù)調(diào)用中的形參(也就是函數(shù)名所帶的參數(shù))的值,是怎么理解。有兩種形式的
1)值傳遞:即使是值傳遞,在函數(shù)體中,改變的也只是一個(gè)臨時(shí)變量的值。并不會(huì)影響到實(shí)參的值
2)引用傳遞:對(duì)象間的傳遞,而這傳遞只是引用關(guān)系的傳遞。就是將該參數(shù)指向該類,如果在函數(shù)體中設(shè)為null,也只是將形參與實(shí)際對(duì)象間的引用關(guān)系給去掉
本程序中,是屬于引用傳遞,在createbintree將myTree=null,也只是斷掉myTree與外部對(duì)象的關(guān)系而已,即父節(jié)點(diǎn)1的左孩子間的關(guān)系,所以父節(jié)點(diǎn)1的左孩子不為null
3.與2同樣的解釋,也可知道右孩子也不為空。
那么在調(diào)用num來(lái)計(jì)算葉子的個(gè)數(shù)時(shí)候,是不是根結(jié)點(diǎn)一開(kāi)始進(jìn)來(lái),左右孩子都不為null,所以自然最后一個(gè)else。那么往下,lz再計(jì)算一下就知道結(jié)果為2
建議修改的話:
在createbintree方法中,if ("".equals(str.trim()))為空時(shí),則myTree.data=null
然后在num方法中,計(jì)算個(gè)數(shù)的話,利用myTree.data==null return 0 ; myTree.lchild.data==null myTree.rchild.data==null return 1 ; else 一樣
//獲得商品分類樹(shù)形結(jié)構(gòu)
private JTree getTree(){
if(tree ==null)
{
tree = new JTree(getTreeModel());
tree.setBorder(new EtchedBorder(EtchedBorder.LOWERED));
// tree = new JTable(getModel());
tree.getSelectionModel().setSelectionMode(
TreeSelectionModel.SINGLE_TREE_SELECTION);
// 節(jié)點(diǎn)選擇事件
tree.addTreeSelectionListener(new TreeSelectionListener() {
public void valueChanged(TreeSelectionEvent e) {
treeSelection();
}
});
tree.addMouseListener(new MouseAdapter(){
public void mousePressed(MouseEvent e){
if(e.getButton()==MouseEvent.BUTTON3)
{
int selRow = tree.getRowForLocation(e.getX(), e.getY());
tree.setSelectionRow(selRow);
TreePath selPath = tree.getPathForLocation(e.getX(), e.getY());
if(selRow != -1) {
if(e.getClickCount() == 1) {
// myRightClick(selRow, selPath);
selectedNode = (DefaultMutableTreeNode) selPath.getLastPathComponent();
showPopMenu(selRow,selPath,e.getX(),e.getY());
}
}
}
}
});
}
return tree;
}
/**
* 獲得當(dāng)前選擇的商品對(duì)象
* @return
*
*/
private Goods getSelectedGoods(){
int row = table.getSelectedRow();
if(row!=-1)
{
String code = (String)getModel().getValueAt(row,0);
Goods g= gHandle.getGoodsByCode(code);
return g;
}
return null;
}
/**
* 樹(shù)形結(jié)構(gòu)上顯示右鍵菜單
* @param selRow
* @param selPath
*
*/
private void showPopMenu(int selRow, TreePath path,int x,int y) {
// tree.add(getPopMenu());
if (path == null)
return;
//點(diǎn)的是根結(jié)點(diǎn)
if(selectedNode.isRoot())
{
JPopupMenu pop = getPopMenu(1,path,selRow);
// System.out.println(selRow);
this.getContentPane().add(pop);
pop.show(tree,x,y);
}
//葉結(jié)點(diǎn)
if(selectedNode.isLeaf())
{
JPopupMenu pop = getPopMenu(0,path,selRow);
this.getContentPane().add(pop);
pop.show(tree,x,y);
}
}
/**
* 創(chuàng)建右鍵菜單
* @param action
* @return
*
*/
private JPopupMenu getPopMenu(int action,final TreePath path,final int selRow){
if(pop==null)
{
pop = new JPopupMenu();
//新建類別事件處理
addItem.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e) {
String value = JOptionPane.showInputDialog("請(qǐng)輸入新類別的名稱:");
if(value==null||value.trim().length()==0)
return;
GoodsCategoryHandle gcHandle = new GoodsCategoryHandle();
if(gcHandle.isExsited(value))
{
JOptionPane.showMessageDialog(null, "該類別名稱已經(jīng)存在!", "提示", JOptionPane.ERROR_MESSAGE);
return ;
}
DefaultMutableTreeNode newNode =new DefaultMutableTreeNode(value);
treeModel.insertNodeInto(newNode,(MutableTreeNode)treeModel.getRoot(),selRow-1);
GoodsCategory gc = new GoodsCategory();
gc.setCategoryName(value);
//更新到數(shù)據(jù)庫(kù)中
gcHandle.addCategory(gc);
}
});
//重命名類別名稱事件處理
renameItem.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e) {
String value = JOptionPane.showInputDialog(null,"請(qǐng)輸入新類別的名稱:",selectedNode.toString());
if(value==null||value.trim().length()==0)
return;
GoodsCategoryHandle gcHandle = new GoodsCategoryHandle();
if(gcHandle.isExsited(value))
{
JOptionPane.showMessageDialog(null, "該類別名稱已經(jīng)存在!", "提示", JOptionPane.ERROR_MESSAGE);
return ;
}
GoodsCategory gc =gcHandle.getCategory(selectedNode.toString());
gc.setCategoryName(value);
//更新到數(shù)據(jù)庫(kù)中
gcHandle.modifyCategory(gc);
selectedNode.setUserObject(value);
tree.setModel(getTreeModel());
}
});
//移除結(jié)點(diǎn)事件處理
delItem.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e) {
int i =JOptionPane.showConfirmDialog(null,
"慎重!刪除類別后,該類別下的所有商品將全部被刪除,確認(rèn)后繼續(xù)", "提示", JOptionPane.YES_NO_OPTION);
if(i==JOptionPane.YES_OPTION)
{
GoodsCategoryHandle gcHandle = new GoodsCategoryHandle();
GoodsHandle gHandle = new GoodsHandle();
int id = (gcHandle.getCategory(selectedNode.toString().trim())).getCategoryId();
ArrayList al = gHandle.getGoodsByCategory(id);
boolean b_bak = false;
//對(duì)刪除商品的備分
try {
FileWriter out = new FileWriter("/"+CommonUtil.getTime()+"商品刪除bak.db",true);
out.write("商品名稱"+" "+"商品分類"+" "+
"商品別名"+" "+"商品單位"+" "+
"商品廠商"+" "+"商品庫(kù)存上限"+" "+
"商品庫(kù)存下限"+" "+
"商品庫(kù)存下限"+" "+
"商品參考售價(jià)"+" "+
"商品實(shí)際庫(kù)存");
out.write('\n');
for(int j=0;jal.size();j++)
{
Goods g = (Goods)al.get(j);
out.write(g.toString());
out.write('\n');
}
out.close();
b_bak=true;
} catch (IOException e1) {
e1.printStackTrace();
b_bak = false;
}
gcHandle.setCommit(false);
boolean g_del=gHandle.deleteByCategoryId(id);
boolean gc_del=gcHandle.deleteById(id);
//只有類別刪除成功,該類別下的商品刪除成功,并且備分成功后才提交刪除
if(g_delgc_delb_bak)
gcHandle.commit();
else
{
// System.out.println("fail");
gcHandle.rollBack();
JOptionPane.showMessageDialog(null, "刪除失敗,可能是因?yàn)樵擃悇e下的商品存在銷售記錄,不能被刪除!", "提示", JOptionPane.ERROR_MESSAGE);
}
tree.setModel(getTreeModel());
tree.setSelectionRow(0);
}
else
return;
}
});
pop.add(addItem);
pop.add(delItem);
pop.add(renameItem);
}
if(action ==1)
{
delItem.setEnabled(false);
renameItem.setEnabled(false);
}
if(action ==0)
{
delItem.setEnabled(true);
renameItem.setEnabled(true);
}
return pop;
}
/**
* 用戶在商品分類樹(shù)上的事件處理
*
*
*/
private void treeSelection(){
TreePath path = tree.getSelectionPath();
if (path == null)
return;
DefaultMutableTreeNode node = (DefaultMutableTreeNode) path
.getLastPathComponent();
selectedCategory = cHandle.getCategory(node.toString());
// 若選中的是根節(jié)點(diǎn)
if (node.isRoot())
showAllGoods();
if(node.isLeaf()){
model.setRowCount(0);
ArrayList al = gHandle.getGoodsByCategoryName(node
.toString());
for (int i = 0; i al.size(); i++) {
Goods g = (Goods) al.get(i);
model.addRow(getRow(g));
}
}
}
public GoodsCategory getCategory(){
return this.selectedCategory;
}
/**
* 生產(chǎn)樹(shù)形列表的數(shù)據(jù)模型
*
* @return
*
*/
private TreeModel getTreeModel() {
DefaultMutableTreeNode root = new DefaultMutableTreeNode(
PropertiesUtil.getString("categoryTree.all"));
ArrayList categoryList = cHandle.getAllCategory();
// 添加子節(jié)點(diǎn)
for (int i = 0; i categoryList.size(); i++) {
GoodsCategory gc = (GoodsCategory) categoryList.get(i);
String name = gc.getCategoryName();
DefaultMutableTreeNode node = new DefaultMutableTreeNode(name);
root.add(node);
}
// 生產(chǎn)treeModel
treeModel = new DefaultTreeModel(root);
return treeModel;
}