Java數據結構(二叉數基礎與遍歷篇)

二叉樹:在計算機科學中,樹是一種重要的非線性數據結構,直觀地看,它是數據元素(在樹中稱爲結點)按分支關係組織起來的結構。二叉樹是每個節點最多有兩個子樹的有序樹。通常子樹被稱作“左子樹”(left subtree)和“右子樹”(right subtree)。二叉樹常被用於實現二叉查找樹二叉堆。值得注意的是,二叉樹不是樹的特殊情形。在圖論中,二叉樹是一個連通的無環圖,並且每一個頂點的度不大於3。有根二叉樹還要滿足根結點的度不大於2。有了根結點後,每個頂點定義了唯一的根結點,和最多2個子結點。然而,沒有足夠的信息來區分左結點和右結點。


Node節點:

package ch06BinaryTree;

public class Node {

	// 關鍵字
	private int keyData;
	
	// 其他數據
	private int otherData;
	
	// 左子節點
	private Node leftNode;
	
	// 右子節點
	private Node rightNode;

	public Node(int keyData, int otherData) {
		this.keyData = keyData;
		this.otherData = otherData;
	}

	public int getKeyData() {
		return keyData;
	}

	public void setKeyData(int keyData) {
		this.keyData = keyData;
	}

	public int getOtherData() {
		return otherData;
	}

	public void setOtherData(int otherData) {
		this.otherData = otherData;
	}

	public Node getLeftNode() {
		return leftNode;
	}

	public void setLeftNode(Node leftNode) {
		this.leftNode = leftNode;
	}

	public Node getRightNode() {
		return rightNode;
	}

	public void setRightNode(Node rightNode) {
		this.rightNode = rightNode;
	}
	
	public void dispaly(){
		System.out.println(keyData + "," + otherData);
	}
}

二叉樹:

package ch06BinaryTree;

public class Tree {

	// 根
	private Node root;
	
	// 插入方法
	public void insert(int keyData, int otherData){
		Node newNode = new Node(keyData, otherData);
		if(root == null)
			root = newNode;
		else {
			Node current = root;
			Node parent;
			while(true){
				parent = current;
				if(keyData < current.getKeyData()){
					current = current.getLeftNode();
					if(current == null){
						parent.setLeftNode(newNode);
						return;
					}
				}else{
					current = current.getRightNode();
					if(current == null){
						parent.setRightNode(newNode);
						return;
					}
				}
			}
		}
	}
	
	// 查找方法
	public Node find(int keyData){
		Node current = root;
		while(current.getKeyData() != keyData){
			if(current.getKeyData() > keyData)
				current = current.getLeftNode();
			else
				current = current.getRightNode();
			if(current == null)
				return null;
		}
		return current;
	}
	
	// 修改方法
	public void change(int keyData, int otherData){
		Node findNode = find(keyData);
		findNode.setOtherData(otherData);
	}
	
	// 先序遍歷
	public void preOrder(Node node){
		if(node != null){
			node.dispaly();
			preOrder(node.getLeftNode());
			preOrder(node.getRightNode());
		}
	}
	
	// 中序遍歷
	public void inOrder(Node node){
		if(node != null){
			inOrder(node.getLeftNode());
			node.dispaly();
			inOrder(node.getRightNode());
		}
	}
	
	// 後續遍歷
	public void endOrder(Node node){
		if(node != null){
			endOrder(node.getLeftNode());
			endOrder(node.getRightNode());
			node.dispaly();
		}
	}
	
	// 得到根節點
	public Node getRoot(){
		return root;
	}
	
}

測試:

package ch06BinaryTree;

public class TestTree {

	public static void main(String[] args) {
		Tree tree = new Tree();
		
		tree.insert(80, 80);
		tree.insert(49, 49);
		tree.insert(42, 42);
		tree.insert(30, 30);
		tree.insert(45, 45);
		tree.insert(90, 90);
		tree.insert(150, 150);
		tree.insert(130, 130);
		tree.insert(82, 82);
		
		//tree.find(30).dispaly();
		
		//tree.change(30, 520);
		//tree.find(30).dispaly();
		
		tree.preOrder(tree.getRoot());
		System.out.println("---------");
		tree.inOrder(tree.getRoot());
		System.out.println("---------");
		tree.endOrder(tree.getRoot());
	}
}

結果:

80,80
49,49
42,42
30,30
45,45
90,90
82,82
150,150
130,130
---------
30,30
42,42
45,45
49,49
80,80
82,82
90,90
130,130
150,150
---------
30,30
45,45
42,42
49,49
82,82
130,130
150,150
90,90
80,80

以下來自百度百科:

遍歷是對樹的一種最基本的運算,所謂遍歷二叉樹,就是按一定的規則和順序走遍二叉樹的所有結點,使每一個結點都被訪問一次,而且只被訪問一次。由於二叉樹是非線性結構,因此,樹的遍歷實質上是將二叉樹的各個結點轉換成爲一個線性序列來表示。
設L、D、R分別表示遍歷左子樹、訪問根結點和遍歷右子樹, 則對一棵二叉樹的遍歷有三種情況:DLR(稱爲先根次序遍歷),LDR(稱爲中根次序遍歷),LRD (稱爲後根次序遍歷)。
首先訪問根,再先序遍歷左(右)子樹,最後先序遍歷右(左)子樹,C語言代碼如下:
void XXBL(tree* root)
{
//Do Something with root
if (root->lchild!=NULL)
XXBL(root->lchild);
if (root->rchild!=NULL)
XXBL(root->rchild);
}
首先中序遍歷左(右)子樹,再訪問根,最後中序遍歷右(左)子樹,C語言代碼如下
void ZXBL(tree* root)
{
if(root->lchild!=NULL)
ZXBL(root->lchild);
//Do Something with root
if(root->rchild!=NULL)
ZXBL(root->rchild);
}
首先後序遍歷左(右)子樹,再後序遍歷右(左)子樹,最後訪問根,C語言代碼如下
void HXBL(tree* root)
{
if (root->lchild!=NULL)
HXBL(root->lchild);
if (root->rchild!=NULL)
HXBL(root->rchild);
//Do Something with root
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章