① 如何用java實現二叉樹
import java.util.List;
import java.util.LinkedList;
public class Bintrees {
private int[] array = {1, 2, 3, 4, 5, 6, 7, 8, 9};
private static List<Node> nodeList = null;
private static class Node {
Node leftChild;
Node rightChild;
int data;
Node(int newData) {
leftChild = null;
rightChild = null;
data = newData;
}
}
// 創建二叉樹
public void createBintree() {
nodeList = new LinkedList<Node>();
// 將數組的值轉換為node
for (int nodeIndex = 0; nodeIndex < array.length; nodeIndex++) {
nodeList.add(new Node(array[nodeIndex]));
}
// 對除最後一個父節點按照父節點和孩子節點的數字關系建立二叉樹
for (int parentIndex = 0; parentIndex < array.length / 2 - 1; parentIndex++) {
nodeList.get(parentIndex).leftChild = nodeList.get(parentIndex * 2 + 1);
nodeList.get(parentIndex).rightChild = nodeList.get(parentIndex * 2 + 2);
}
// 最後一個父節點
int lastParentIndex = array.length / 2 - 1;
// 左孩子
nodeList.get(lastParentIndex).leftChild = nodeList.get(lastParentIndex * 2 + 1);
// 如果為奇數,建立右孩子
if (array.length % 2 == 1) {
nodeList.get(lastParentIndex).rightChild = nodeList.get(lastParentIndex * 2 + 2);
}
}
// 前序遍歷
public static void preOrderTraverse(Node node) {
if (node == null) {
return;
}
System.out.print(node.data + " ");
preOrderTraverse(node.leftChild);
preOrderTraverse(node.rightChild);
}
// 中序遍歷
public static void inOrderTraverse(Node node) {
if (node == null) {
return;
}
inOrderTraverse(node.leftChild);
System.out.print(node.data + " ");
inOrderTraverse(node.rightChild);
}
// 後序遍歷
public static void postOrderTraverse(Node node) {
if (node == null) {
return;
}
postOrderTraverse(node.leftChild);
postOrderTraverse(node.rightChild);
System.out.print(node.data + " ");
}
public static void main(String[] args) {
Bintrees binTree = new Bintrees();
binTree.createBintree();
Node root = nodeList.get(0);
System.out.println("前序遍歷:");
preOrderTraverse(root);
System.out.println();
System.out.println("中序遍歷:");
inOrderTraverse(root);
System.out.println();
System.out.println("後序遍歷:");
postOrderTraverse(root);
}
}
輸出結果:
前序遍歷:
1 2 4 8 9 5 3 6 7
中序遍歷:
8 4 9 2 5 1 6 3 7
後序遍歷:
8 9 4 5 2 6 7 3 1
② java實現二叉樹的問題
/**
* 二叉樹測試二叉樹順序存儲在treeLine中,遞歸前序創建二叉樹。另外還有能
* 夠前序、中序、後序、按層遍歷二叉樹的方法以及一個返回遍歷結果asString的
* 方法。
*/
public class BitTree {
public static Node2 root;
public static String asString;
//事先存入的數組,符號#表示二叉樹結束。
public static final char[] treeLine = {'a','b','c','d','e','f','g',' ',' ','j',' ',' ','i','#'};
//用於標志二叉樹節點在數組中的存儲位置,以便在創建二叉樹時能夠找到節點對應的數據。
static int index;
//構造函數
public BitTree() {
System.out.print("測試二叉樹的順序表示為:");
System.out.println(treeLine);
this.index = 0;
root = this.setup(root);
}
//創建二叉樹的遞歸程序
private Node2 setup(Node2 current) {
if (index >= treeLine.length) return current;
if (treeLine[index] == '#') return current;
if (treeLine[index] == ' ') return current;
current = new Node2(treeLine[index]);
index = index * 2 + 1;
current.left = setup(current.left);
index ++;
current.right = setup(current.right);
index = index / 2 - 1;
return current;
}
//二叉樹是否為空。
public boolean isEmpty() {
if (root == null) return true;
return false;
}
//返回遍歷二叉樹所得到的字元串。
public String toString(int type) {
if (type == 0) {
asString = "前序遍歷:\t";
this.front(root);
}
if (type == 1) {
asString = "中序遍歷:\t";
this.middle(root);
}
if (type == 2) {
asString = "後序遍歷:\t";
this.rear(root);
}
if (type == 3) {
asString = "按層遍歷:\t";
this.level(root);
}
return asString;
}
//前序遍歷二叉樹的循環演算法,每到一個結點先輸出,再壓棧,然後訪問它的左子樹,
//出棧,訪問其右子樹,然後該次循環結束。
private void front(Node2 current) {
StackL stack = new StackL((Object)current);
do {
if (current == null) {
current = (Node2)stack.pop();
current = current.right;
} else {
asString += current.ch;
current = current.left;
}
if (!(current == null)) stack.push((Object)current);
} while (!(stack.isEmpty()));
}
//中序遍歷二叉樹
private void middle(Node2 current) {
if (current == null) return;
middle(current.left);
asString += current.ch;
middle(current.right);
}
//後序遍歷二叉樹的遞歸演算法
private void rear(Node2 current) {
if (current == null) return;
rear(current.left);
rear(current.right);
asString += current.ch;
}
}
/**
* 二叉樹所使用的節點類。包括一個值域兩個鏈域
*/
public class Node2 {
char ch;
Node2 left;
Node2 right;
//構造函數
public Node2(char c) {
this.ch = c;
this.left = null;
this.right = null;
}
//設置節點的值
public void setChar(char c) {
this.ch = c;
}
//返回節點的值
public char getChar() {
return ch;
}
//設置節點的左孩子
public void setLeft(Node2 left) {
this.left = left;
}
//設置節點的右孩子
public void setRight (Node2 right) {
this.right = right;
}
//如果是葉節點返回true
public boolean isLeaf() {
if ((this.left == null) && (this.right == null)) return true;
return false;
}
}
一個作業題,裡面有你要的東西。
主函數自己寫吧。當然其它地方也有要改的。
③ 用java怎麼構造一個二叉樹呢
二叉樹的相關操作,包括創建,中序、先序、後序(遞歸和非遞歸),其中重點的是java在先序創建二叉樹和後序非遞歸遍歷的的實現。
package com.algorithm.tree;
import java.io.File;
import java.io.FileNotFoundException;
import java.util.Queue;
import java.util.Scanner;
import java.util.Stack;
import java.util.concurrent.LinkedBlockingQueue;
public class Tree<T> {
private Node<T> root;
public Tree() {
}
public Tree(Node<T> root) {
this.root = root;
}
//創建二叉樹
public void buildTree() {
Scanner scn = null;
try {
scn = new Scanner(new File("input.txt"));
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
root = createTree(root,scn);
}
//先序遍歷創建二叉樹
private Node<T> createTree(Node<T> node,Scanner scn) {
String temp = scn.next();
if (temp.trim().equals("#")) {
return null;
} else {
node = new Node<T>((T)temp);
node.setLeft(createTree(node.getLeft(), scn));
node.setRight(createTree(node.getRight(), scn));
return node;
}
}
//中序遍歷(遞歸)
public void inOrderTraverse() {
inOrderTraverse(root);
}
public void inOrderTraverse(Node<T> node) {
if (node != null) {
inOrderTraverse(node.getLeft());
System.out.println(node.getValue());
inOrderTraverse(node.getRight());
}
}
//中序遍歷(非遞歸)
public void nrInOrderTraverse() {
Stack<Node<T>> stack = new Stack<Node<T>>();
Node<T> node = root;
while (node != null || !stack.isEmpty()) {
while (node != null) {
stack.push(node);
node = node.getLeft();
}
node = stack.pop();
System.out.println(node.getValue());
node = node.getRight();
}
}
//先序遍歷(遞歸)
public void preOrderTraverse() {
preOrderTraverse(root);
}
public void preOrderTraverse(Node<T> node) {
if (node != null) {
System.out.println(node.getValue());
preOrderTraverse(node.getLeft());
preOrderTraverse(node.getRight());
}
}
//先序遍歷(非遞歸)
public void nrPreOrderTraverse() {
Stack<Node<T>> stack = new Stack<Node<T>>();
Node<T> node = root;
while (node != null || !stack.isEmpty()) {
while (node != null) {
System.out.println(node.getValue());
stack.push(node);
node = node.getLeft();
}
node = stack.pop();
node = node.getRight();
}
}
//後序遍歷(遞歸)
public void postOrderTraverse() {
postOrderTraverse(root);
}
public void postOrderTraverse(Node<T> node) {
if (node != null) {
postOrderTraverse(node.getLeft());
postOrderTraverse(node.getRight());
System.out.println(node.getValue());
}
}
//後續遍歷(非遞歸)
public void nrPostOrderTraverse() {
Stack<Node<T>> stack = new Stack<Node<T>>();
Node<T> node = root;
Node<T> preNode = null;//表示最近一次訪問的節點
while (node != null || !stack.isEmpty()) {
while (node != null) {
stack.push(node);
node = node.getLeft();
}
node = stack.peek();
if (node.getRight() == null || node.getRight() == preNode) {
System.out.println(node.getValue());
node = stack.pop();
preNode = node;
node = null;
} else {
node = node.getRight();
}
}
}
//按層次遍歷
public void levelTraverse() {
levelTraverse(root);
}
public void levelTraverse(Node<T> node) {
Queue<Node<T>> queue = new LinkedBlockingQueue<Node<T>>();
queue.add(node);
while (!queue.isEmpty()) {
Node<T> temp = queue.poll();
if (temp != null) {
System.out.println(temp.getValue());
queue.add(temp.getLeft());
queue.add(temp.getRight());
}
}
}
}
//樹的節點
class Node<T> {
private Node<T> left;
private Node<T> right;
private T value;
public Node() {
}
public Node(Node<T> left,Node<T> right,T value) {
this.left = left;
this.right = right;
this.value = value;
}
public Node(T value) {
this(null,null,value);
}
public Node<T> getLeft() {
return left;
}
public void setLeft(Node<T> left) {
this.left = left;
}
public Node<T> getRight() {
return right;
}
public void setRight(Node<T> right) {
this.right = right;
}
public T getValue() {
return value;
}
public void setValue(T value) {
this.value = value;
}
}
測試代碼:
package com.algorithm.tree;
public class TreeTest {
/**
* @param args
*/
public static void main(String[] args) {
Tree<Integer> tree = new Tree<Integer>();
tree.buildTree();
System.out.println("中序遍歷");
tree.inOrderTraverse();
tree.nrInOrderTraverse();
System.out.println("後續遍歷");
//tree.nrPostOrderTraverse();
tree.postOrderTraverse();
tree.nrPostOrderTraverse();
System.out.println("先序遍歷");
tree.preOrderTraverse();
tree.nrPreOrderTraverse();
//
}
}
④ java中的遍歷是什麼意思
遍歷就是把每個元素都訪問一次.比如一個二叉樹,遍歷二叉樹意思就是把二叉樹中的每個元素都訪問一次
⑤ java 構建二叉樹
首先我想問為什麼要用LinkedList 來建立二叉樹呢? LinkedList 是線性表,
樹是樹形的, 似乎不太合適。
其實也可以用數組完成,而且效率更高.
關鍵是我覺得你這個輸入本身就是一個二叉樹啊,
String input = "ABCDE F G";
節點編號從0到8. 層次遍歷的話:
對於節點i.
leftChild = input.charAt(2*i+1); //做子樹
rightChild = input.charAt(2*i+2);//右子樹
如果你要將帶有節點信息的樹存到LinkedList裡面, 先建立一個節點類:
class Node{
public char cValue;
public Node leftChild;
public Node rightChild;
public Node(v){
this.cValue = v;
}
}
然後遍歷input,建立各個節點對象.
LinkedList tree = new LinkedList();
for(int i=0;i< input.length;i++)
LinkedList.add(new Node(input.charAt(i)));
然後為各個節點設置左右子樹:
for(int i=0;i<input.length;i++){
((Node)tree.get(i)).leftChild = (Node)tree.get(2*i+1);
((Node)tree.get(i)).rightChild = (Node)tree.get(2*i+2);
}
這樣LinkedList 就存儲了整個二叉樹. 而第0個元素就是樹根,思路大體是這樣吧。
⑥ java Map 怎麼遍歷
關於java中遍歷map具體有四種方式,請看下文詳解。
1、這是最常見的並且在大多數情況下也是最可取的遍歷方式,在鍵值都需要時使用。
Map<Integer, Integer> map = newHashMap<Integer, Integer>();
for(Map.Entry<Integer, Integer> entry : map.entrySet()) {
System.out.println("Key = "+ entry.getKey() + ", Value = "+ entry.getValue());
}
2、在for-each循環中遍歷keys或values。
如果只需要map中的鍵或者值,你可以通過keySet或values來實現遍歷,而不是用entrySet。
Map<Integer, Integer> map = newHashMap<Integer, Integer>();
for(Integer key : map.keySet()) {
System.out.println("Key = "+ key);
}
for(Integer value : map.values()) {
System.out.println("Value = "+ value);
}
該方法比entrySet遍歷在性能上稍好(快了10%),而且代碼更加干凈。
3、使用Iterator遍歷
使用泛型:
Map<Integer, Integer> map = newHashMap<Integer, Integer>();
Iterator<Map.Entry<Integer, Integer>> entries = map.entrySet().iterator();
while(entries.hasNext()) {
Map.Entry<Integer, Integer> entry = entries.next();
System.out.println("Key = "+ entry.getKey() + ", Value = "+ entry.getValue());
}
不使用泛型:
Map map = newHashMap();
Iterator entries = map.entrySet().iterator();
while(entries.hasNext()) {
Map.Entry entry = (Map.Entry) entries.next();
Integer key = (Integer)entry.getKey();
Integer value = (Integer)entry.getValue();
System.out.println("Key = "+ key + ", Value = "+ value);
}
4、通過鍵找值遍歷(效率低)
Map<Integer, Integer> map = newHashMap<Integer, Integer>();
for(Integer key : map.keySet()) {
Integer value = map.get(key);
System.out.println("Key = "+ key + ", Value = "+ value);
}
假設Map中的鍵值對為1=>11,2=>22,3=>33,現用方法1來遍歷Map代碼和調試結果如下:
(6)二叉樹的遍歷演算法java擴展閱讀:
1、HashMap的重要參數
HashMap 的實例有兩個參數影響其性能:初始容量 和載入因子。容量是哈希表中桶的數量,初始容量只是哈希表在創建時的容量。
載入因子 是哈希表在其容量自動增加之前可以達到多滿的一種尺度。當哈希表中的條目數超出了載入因子與當前容量的乘積時,則要對該哈希表進行 rehash 操作(即重建內部數據結構),從而哈希表將具有大約兩倍的桶數。
在Java編程語言中,載入因子默認值為0.75,默認哈希表元為101。
2、HashMap的同步機制
注意,此實現不是同步的。 如果多個線程同時訪問一個哈希映射,而其中至少一個線程從結構上修改了該映射,則它必須保持外部同步。
(結構上的修改是指添加或刪除一個或多個映射關系的任何操作;以防止對映射進行意外的非同步訪問,如下:
Map m = Collections.synchronizedMap(new HashMap(...));
⑦ 我想要找一份關於java數據結構二叉樹的實例詳解(所有基本操作,包括二叉樹的高度和節點總數)
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#define Max 20 //結點的最大個數
typedef struct node{
char data;
struct node *lchild,*rchild;
}BinTNode; //自定義二叉樹的結點類型
typedef BinTNode *BinTree; //定義二叉樹的指針
int NodeNum,leaf; //NodeNum為結點數,leaf為葉子數
//基於先序遍歷演算法創建二叉樹
//要求輸入先序序列,其中加入虛結點"#"以示空指針的位置
BinTree CreatBinTree(void){
BinTree T;
char ch;
if((ch=getchar())=='#')
return(NULL); //讀入#,返回空指針
else{
T=(BinTNode *)malloc(sizeof(BinTNode)); //生成結點
T->data=ch;
T->lchild=CreatBinTree(); //構造左子樹
T->rchild=CreatBinTree(); //構造右子樹
return(T);
}
}
//先序遍歷
void Preorder(BinTree T){
if(T){
printf("%c",T->data); //訪問結點
Preorder(T->lchild); //先序遍歷左子樹
Preorder(T->rchild); //先序遍歷右子樹
}
}
//中序遍歷
void Inorder(BinTree T){
if(T){
Inorder(T->lchild); //中序遍歷左子樹
printf("%c",T->data); //訪問結點
Inorder(T->rchild); //中序遍歷右子樹
}
}
//後序遍歷
void Postorder(BinTree T){
if(T){
Postorder(T->lchild); //後序遍歷左子樹
Postorder(T->rchild); //後序遍歷右子樹
printf("%c",T->data); //訪問結點
}
}
//採用後序遍歷求二叉樹的深度、結點數及葉子數的遞歸演算法
int TreeDepth(BinTree T){
int hl,hr,max;
if(T){
hl=TreeDepth(T->lchild); //求左深度
hr=TreeDepth(T->rchild); //求右深度
max=hl>hr? hl:hr; //取左右深度的最大值
NodeNum=NodeNum+1; //求結點數
if(hl==0&&hr==0) leaf=leaf+1; //若左右深度為0,即為葉子。
return(max+1);
}
else return(0);
}
//主函數
void main(){
BinTree root;
int i,depth;
printf("\n");
printf("Creat Bin_Tree; Input preorder:"); //輸入完全二叉樹的先序序列,
// 用#代表虛結點,如ABD###CE##F##
root=CreatBinTree(); //創建二叉樹,返回根結點
do{ //從菜單中選擇遍歷方式,輸入序號。
printf("\t********** select ************\n");
printf("\t1: Preorder Traversal\n");
printf("\t2: Iorder Traversal\n");
printf("\t3: Postorder traversal\n");
printf("\t4: PostTreeDepth,Node number,Leaf number\n");
printf("\t0: Exit\n");
printf("\t*******************************\n");
scanf("%d",&i); //輸入菜單序號(0-4)
switch (i){
case 1: printf("Print Bin_tree Preorder: ");
Preorder(root); //先序遍歷
break;
case 2: printf("Print Bin_Tree Inorder: ");
Inorder(root); //中序遍歷
break;
case 3: printf("Print Bin_Tree Postorder: ");
Postorder(root); //後序遍歷
break;
case 4: depth=TreeDepth(root); //求樹的深度及葉子數
printf("BinTree Depth=%d BinTree Node number=%d",depth,NodeNum);
printf(" BinTree Leaf number=%d",leaf);
break;
case 5: printf("LevePrint Bin_Tree: ");
Levelorder(root); //按層次遍歷
break;
default: exit(1);
}
printf("\n");
}while(i!=0);
}
//按層遍歷
Levelorder( BinTNode *root){
BinTNode * q[Max]; //定義BinTNode類型的隊列 用於存放節點 隊列長最大為20個元素
int front=0,rear=0; //初始化隊列為空
BinTNode *p; //臨時節點指針
if(root!=NULL){ //將根節點進隊
rear=(rear+1)%Max;
q[rear]=root;
}
while(front!=rear){
front=(front+1)%Max;
p=q[front]; //刪除隊首的元素 讓兩個節點(左右節點)孤立
printf("%c",p->data); //輸出隊列首元素的值
if(p->left!=null){ //如果存在左孩子節點,則左孩子節點進入隊列
rear=(rear+1)%Max;
q[rear]=p->left;
}
if(p->right!=null){ //如果存在右孩子節點,則右孩子節點進入隊列
rear=(rear+1)%Max;
q[rear]=p->right;
}
}
}