データ構造:ツリーのapi設計とjavaコード実装
9516 ワード
二叉木の基本的な概念について
ツリー:ツリーは度が2を超えないツリーです(ノードごとに最大2つのサブノードがあります)
フルツリー:各レイヤのノード数が最大値に達すると、このツリーはフルツリーになります.
完全二叉樹:葉の結点は最下層とこの下層にしか現れず、最下層の結点はその層の最も左側のいくつかの位置に集中している二叉樹、すなわち木が不満であれば左満右が不満であり、完全二叉樹である
二叉木の結点の特性を解析した後,二叉木の結点クラスを容易に設計した.
次に,二叉ルックアップツリーのAPI設計を解析する.
類名:BinaryTree,V value>メンバー変数:private Node rootレコードルートノードprivate int Nレコードツリーの要素個数メンバーメソッド:public void put(K key,V value)ツリーにキー値対private Node put(Node,K key,V value)を挿入ツリーに指定したノードにキー値対public V get(K key)を挿入ツリーのキー対応値private V get(Node,K key,K key)を検索ツリーで指定したノードxからキー対応値public void delete(K key)キー値対private Node delete(Node x,K key)キー削除ツリーで指定したノードのキー値対public int size()ツリーの要素数を取得する
BinaryTree完全javaコード実装
二叉樹前序遍歴:まずルートノードを遍歴し、次に左サブツリーを遍歴し、最後に右サブツリー二叉樹中序遍歴:まず左サブツリーを遍歴し、次にルートノードを遍歴し、最後に右サブツリー二叉樹後序遍歴:まず左サブツリーを遍歴し、次に右サブツリーを遍歴し、最後にルートノードを遍歴する
二叉木の層順遍歴(広さ優先):最上位(root)から最下層まで、1層1層が順次遍歴し、同じ層の要素が左から右に遍歴する.
ツリー:ツリーは度が2を超えないツリーです(ノードごとに最大2つのサブノードがあります)
フルツリー:各レイヤのノード数が最大値に達すると、このツリーはフルツリーになります.
完全二叉樹:葉の結点は最下層とこの下層にしか現れず、最下層の結点はその層の最も左側のいくつかの位置に集中している二叉樹、すなわち木が不満であれば左満右が不満であり、完全二叉樹である
二叉木の結点の特性を解析した後,二叉木の結点クラスを容易に設計した.
private class Node {
private K key;//
private V value;//
private Node left;//
private Node right;//
public Node(K key,V value,Node left,Node right){
this.key=key;
this.value=value;
this.left=left;
this.right=right;
}
}
次に,二叉ルックアップツリーのAPI設計を解析する.
類名:BinaryTree,V value>メンバー変数:private Node rootレコードルートノードprivate int Nレコードツリーの要素個数メンバーメソッド:public void put(K key,V value)ツリーにキー値対private Node put(Node,K key,V value)を挿入ツリーに指定したノードにキー値対public V get(K key)を挿入ツリーのキー対応値private V get(Node,K key,K key)を検索ツリーで指定したノードxからキー対応値public void delete(K key)キー値対private Node delete(Node x,K key)キー削除ツリーで指定したノードのキー値対public int size()ツリーの要素数を取得する
BinaryTree完全javaコード実装
package com.tingcream.alg.tree;
import com.tingcream.alg.linear.Queue;
/**
* ,
* 1、 ( 、 )
* 2、 ,
*
* BinaryTree
*
*/
public class BinaryTree,V> {
private Node root;//
private int N;//
//
public int size(){
return this.N;
}
public boolean isEmpty(){
return this.N<=0;
}
// put key-value
public void put(K key, V value){
// put
root=put(root,key,value);
}
// x kv, x
public Node put(Node x,K key, V value){
// x , new
if(x==null){
N++;
return new Node(key,value,null,null);
}
// x
// x key
// key x , x
// key x , x
// key x , x value
int cmp=key.compareTo(x.key);
if(cmp>0){
x.right= put(x.right,key,value);
}else if(cmp<0){
x.left=put(x.left,key,value);
}else{//key x , x value
x.value=value;
}
return x;
}
// key value
public V get(K key){
return get(root,key);
}
// x , key
public V get(Node x,K key){
// x null
if(x==null){
return null ;
}
int cmp=key.compareTo(x.key);
if(cmp>0){
// key x , x
return get(x.right,key);
}else if(cmp<0){
// key x , x
return get(x.left,key);
}else{
// key x , key , value
return x.value;
}
}
// key
public void delete(K key){
delete(root,key);
}
// x key , x
public Node delete(Node x,K key){
//x null
if(x==null){
return null;
}
//x null
int cmp=key.compareTo(x.key);
if(cmp>0){
// key x , x
x.right=delete(x.right,key);
}else if(cmp<0){
// key x , x
x.left=delete(x.left,key);
}else{
// key x , x
//
N--;
// x ,
if(x.right==null){
return x.left;
}
//x , ,
if(x.left==null ){
return x.right;
}
// x
//
if(x.right.left==null){
x.right.left=x.left;
x=x.right;
return x;
}else{
Node minNode= x.right;
while(minNode.left!=null){
minNode= minNode.left;
}
//
Node n=x.right;
while(n.left!=null){
if(n.left.left==null){
n.left=null; // , left
}else{
n=n.left;
}
}
// x minNode
// // x minNode
// // x minNode
// minNode.left=x.left;
// minNode.right=x.right;
// // x minNode
// x=minNode;
//x , minNode key、value x key、value
x.key=minNode.key;
x.value=minNode.value;
}
}
return x;
}
//
public K min(){
if(root==null){
return null;
}
return min(root).key;
}
//
private Node min(Node x){
// :while
Node n=x;
while(n.left!=null){
n=n.left;
}
return n;
}
//
public K max(){
if(size()>0){
return null;
}
return max(root).key;
}
//
private Node max(Node x){
// :while
Node n=x;
while(n.right!=null){
n=n.right;
}
return n;
}
// ,
public Queue preErgodic(){
Queue keys= new Queue();//new keys
preErgodic(root,keys);
return keys;
}
// , x keys
private void preErgodic(Node x,Queue keys){
// x , return ( )
if(x==null){
return;
}
// x key keys
// x
// x
// x
keys.enqueue(x.key);
// x ,
if(x.left!=null){
preErgodic(x.left,keys);
}
// x ,
if(x.right!=null){
preErgodic(x.right,keys);
}
}
// ,
public Queue midErgodic(){
Queue keys= new Queue();//new keys
midErgodic(root,keys);
return keys;
}
// , x keys
private void midErgodic(Node x,Queue keys){
// x , return ( )
if(x==null){
return;
}
// x key keys
// x
// x
// x ,
if(x.left!=null){
midErgodic(x.left,keys);
}
// x
keys.enqueue(x.key);
// x ,
if(x.right!=null){
midErgodic(x.right,keys);
}
}
// ,
public Queue afterErgodic(){
Queue keys= new Queue();//new keys
afterErgodic(root,keys);
return keys;
}
// , x keys
private void afterErgodic(Node x,Queue keys){
// x , return ( )
if(x==null){
return;
}
// x key keys
// x
// x
// x ,
if(x.left!=null){
afterErgodic(x.left,keys);
}
// x ,
if(x.right!=null){
afterErgodic(x.right,keys);
}
// x
keys.enqueue(x.key);
}
// , key ( )
public Queue layerErgodic(){
if(isEmpty()){
return null;
}
// , key
Queue keys=new Queue();// keys
Queue nodes=new Queue();//
// root nodes
nodes.enqueue(root);
while(!nodes.isEmpty()){
// , key keys
Node n= nodes.dequeue();
keys.enqueue(n.key);
// ,
if(n.left!=null){
nodes.enqueue(n.left);
}
// ,
if(n.right!=null){
nodes.enqueue(n.right);
}
}
return keys;
}
//
public int maxDepth(){
if(isEmpty()){
return 0;
}
return maxDepth(root);
}
//
private int maxDepth(Node x){
if(x==null){
return 0;
}
// x
// x
// x , +1
int max=0;//x
int maxL=0;//x
int maxR=0;//x
if(x.left!=null){
maxL= maxDepth(x.left);
}
if(x.right!=null){
maxR= maxDepth(x.right);
}
max=(maxL>maxR)?maxL+1:maxR+1;
return max;
}
// Node
private class Node {
private K key;//
private V value;//
private Node left;//
private Node right;//
public Node(K key,V value,Node left,Node right){
this.key=key;
this.value=value;
this.left=left;
this.right=right;
}
}
}
二叉樹前序遍歴:まずルートノードを遍歴し、次に左サブツリーを遍歴し、最後に右サブツリー二叉樹中序遍歴:まず左サブツリーを遍歴し、次にルートノードを遍歴し、最後に右サブツリー二叉樹後序遍歴:まず左サブツリーを遍歴し、次に右サブツリーを遍歴し、最後にルートノードを遍歴する
二叉木の層順遍歴(広さ優先):最上位(root)から最下層まで、1層1層が順次遍歴し、同じ層の要素が左から右に遍歴する.