1. 程式人生 > >如何按層遍歷樹 如何按層遍歷普通樹 注意不是二叉樹 是普通樹

如何按層遍歷樹 如何按層遍歷普通樹 注意不是二叉樹 是普通樹

最近遇到個需求,要求按層遍歷普通樹 ,這裡不是二叉樹,二叉樹的遍歷演算法很多,不在此說明,今天用java演算法來寫寫怎麼從最下面的層 從左往右  逐個往上遍歷一顆普通樹

/**
 * @author hdy
 * @version 建立時間:2013-3-8 下午1:53:19
 * 
 */
public abstract class Component {
public abstract Component getParent();
public abstract List<Component> getChildren();
public abstract DirImportDto getNodeData();
public abstract boolean isLeaf() ;
public abstract void setParent(Component parent) ;
public abstract void setChildren(List<Component> children) ;
public abstract void setNodeData(DirImportDto node) ;
public abstract void setLeaf(boolean isLeaf);
public abstract void iteratorTree(Map<String,List<DirImportDto>> depthMap);
public abstract TreeNode addChildNode(Component node);
public abstract int getDepth();
public abstract void setDepth(int depth);
}

/**
 * @author hdy
 * @version 建立時間:2013-3-8 下午1:52:04
 *  存放每個節點資料的地方
 */
public class DirImportDto {
private int key;
private String dir;
public int getKey() {
return key;
}
public String getDir() {
return dir;
}
public void setKey(int key) {
this.key = key;
}
public void setDir(String dir) {
this.dir = dir;
}

}

/**
 * @author hdy
 * @version 建立時間:2013-3-8 下午1:47:15
 * 樹節點
 */
public class TreeNode extends Component{
private Component parent;
private List<Component> children =new ArrayList<Component>();//孩子
private DirImportDto nodeData;//節點內容
private boolean isLeaf;//是否是葉子節點
private int depth;//層

public TreeNode(){

}
public TreeNode(String nodeDateDir){
DirImportDto importDto = new DirImportDto();
importDto.setDir(nodeDateDir);
this.setNodeData(importDto);
}
public int getDepth() {
return depth;
}
public void setDepth(int depth) {
this.depth = depth;
}
public Component getParent() {
return parent;
}
public List<Component> getChildren() {
return children;
}
 
public boolean isLeaf() {
if(children!=null && children.size()>0){
isLeaf=false;
}else{
isLeaf=true;
}
return isLeaf;
}
public void setParent(Component parent) {
this.parent = parent;
this.setDepth(parent.getDepth()+1);//深度加1
}
public void setChildren(List<Component> children) {
this.children = children;
}
 
public DirImportDto getNodeData() {
return nodeData;
}
public void setNodeData(DirImportDto nodeData) {
this.nodeData = nodeData;
}
public void setLeaf(boolean isLeaf) {
this.isLeaf = isLeaf;
}

public void iteratorTree(Map<String,List<DirImportDto>> depthMap){
this.dealDepthData(depthMap);
if(!isLeaf()){
System.out.println("深度:"+this.getDepth()+"內容:"+this.getNodeData().getDir());
for(Component node:this.getChildren()){
node.iteratorTree(depthMap);
}
}else{//遇到葉子列印此節點
System.out.println("深度:"+this.getDepth()+"內容:"+this.getNodeData().getDir());
}
}
//處理層結構資料:
private void dealDepthData(Map<String,List<DirImportDto>> depthMap){
String key = this.getDepth()+"";
if(depthMap.get(key)!=null){
depthMap.get(key).add(this.getNodeData());
}else{
List<DirImportDto> ls = new ArrayList<DirImportDto>();
ls.add(this.getNodeData());
depthMap.put(key, ls);
}
}
@Override
public TreeNode addChildNode(Component node) {
this.getChildren().add(node);
node.setParent(this);//設定孩子的父節點為自己
return this;
}

}

public class TreeTest {


/**
* @param args
*/
public static void main(String[] args) {
Component root = new TreeNode();
DirImportDto i1 = new DirImportDto();
i1.setKey(1001);
root.setNodeData(i1);
root.setDepth(1);
//---------第一層結束---------
Component node21 = new TreeNode();
DirImportDto i21 = new DirImportDto();
i21.setKey(2001);
node21.setNodeData(i21);

Component node22 = new TreeNode();
DirImportDto i22 = new DirImportDto();
i22.setKey(2002);
node22.setNodeData(i22);

Component node23 = new TreeNode();
DirImportDto i23 = new DirImportDto();
i23.setKey(2003);
node23.setNodeData(i23);

root.addChildNode(node21);
root.addChildNode(node22);
root.addChildNode(node23);
//---------第二層結束--------
Component node31 = new TreeNode();
DirImportDto i31 = new DirImportDto();
i31.setKey(3001);
node31.setNodeData(i31);
Component node32 = new TreeNode();
DirImportDto i32 = new DirImportDto();
i32.setKey(3002);
node32.setNodeData(i32);

node21.addChildNode(node31);
node22.addChildNode(node32);
//-----------第三層結束-------

//普通樹的按層遍歷演算法
Map<String,List<DirImportDto>> depthMap = new HashMap<String,List<DirImportDto>>();
root.iteratorTree(depthMap);
//Set valueSet = depthMap.entrySet();
//Iterator it = valueSet.iterator();
//while(it.hasNext()){
//Object obj = it.next();
//}
Set<String> keySet = depthMap.keySet();
Iterator<String> itKey = keySet.iterator();
while(itKey.hasNext()){
String key = (String)itKey.next();
System.out.println(key);
List<DirImportDto> ls = depthMap.get(key);
for(DirImportDto dto : ls){
System.out.println(">>>"+dto.getKey());
}
}
}


}

輸出結果:

3
>>>3001
>>>3002
2
>>>2001
>>>2002
>>>2003
1
>>>1001

說明 這裡我主要是利用了hashMap 他的key值存放的就是節點當前所處的層,如果遇到相同層上的節點,就放在value中 ,value是個arrayList 

至於樹就是普通的一棵樹,

如果大家有更好的方法 歡迎討論