zoukankan      html  css  js  c++  java
  • Java数据结构——二叉树

    前序遍历——根 左 右

    中序遍历——左 根 右

    后序遍历——左 右 根

    //=================================================
    // File Name       :	BinaryTree
    //------------------------------------------------------------------------------
    // Author          :	Common
    
    //类名:Stack_BinaryTree
    //属性:
    //方法:
    class Stack_BinaryTree{
    	private int maxSize;					//栈的长度
    	private Node[] stackArray;		//创建栈的数组的引用
    	private int top;							//创建栈顶的引用
    	
    	public Stack_BinaryTree(int s) {					//构造函数
    		this.maxSize = s;
    		stackArray = new Node[maxSize]; 		//创建对象
    		top = -1;										//栈顶等于-1
    	}
    	
    	public void push(Node j){		//入栈操作
    		stackArray[++top] = j;			//先把top=-1自加成0,再入栈
    	}
    	
    	public Node pop(){
    		return stackArray[top--];		//弹出当前栈顶的元素后,再自减
    	}
    	
    	public Node peek(){
    		return stackArray[top];		//返回当前栈顶的元素
    	}
    	
    	public boolean isEmpty(){	//栈顶为-1,即栈为空
    		return (top == -1);
    	}
    	
    	public boolean isFull(){			//栈顶为maxSize-1,即栈为满
    		return (top == maxSize-1);
    	}
    	
    }
    
    //类名:Node
    //属性:
    //方法:
    class Node{
    	int iData;
    	double fData;
    	Node leftChild;
    	Node rightChild;
    	
    	public void display(){
    		System.out.println('{');
    		System.out.println(iData);
    		System.out.println(',');
    		System.out.println(fData);
    		System.out.println('}');
    	}
    }
    
    //类名:Tree
    //属性:
    //方法:
    class Tree{
    	public Node root;
    	
    	public Tree(){
    		root = null;
    	}
    	
    	public Node find(int key){			//查找关键字的节点
    		Node current = root;
    		while(current.iData != key){	//不等于就一直循环
    			if(key<current.iData){
    				current = current.leftChild;
    			}else{
    				current = current.rightChild;
    			}
    			if(current == null){
    				return null;
    			}
    		}
    		return current;	
    	}
    	
    	public void insert(int id,double dd){		//插入新的节点
    		Node newNode = new Node();
    		newNode.iData = id;
    		newNode.fData = dd;
    		if(root == null){
    			root = newNode;
    		}else{
    			Node current = root;
    			Node parent;
    			while(true){
    				parent = current;
    				if(newNode.iData<current.iData){		//如果插入的节点的数据小于当前节点的数据
    					current = current.leftChild;
    					if(current == null){
    						parent.leftChild = newNode;			//把父亲节点的左孩子设为新节点
    						return;
    					}
    				}else{														//如果插入的节点的数据大于当前节点的数据
    					current = current.rightChild;
    					if(current == null){
    						parent.rightChild = newNode;		//把父亲节点的右孩子设为新节点
    						return;
    					}
    				}
    			}
    		}
    	}
    	
    	public void displayTree(){			//显示整个二叉树
    		Stack_BinaryTree globalStack = new Stack_BinaryTree(128);		//用来放置每一层的二叉树
    		globalStack.push(root);				//入栈
    		int nBlanks = 32;
    		boolean isRowEmpty = false;
    		System.out.println(".............................................");
    		while(isRowEmpty==false){
    			Stack_BinaryTree localStack = new Stack_BinaryTree(128);	//用来放置下一层的二叉树
    			isRowEmpty = true;
    			for(int j=0;j<nBlanks;j++){
    				System.out.print(' ');
    			}
    			
    			while(globalStack.isEmpty()==false){				//当globalStack不为空,就一直出栈
    				Node temp = (Node)globalStack.pop();		//temp等于globalStack出栈的节点
    				if(temp!=null){
    					System.out.print(temp.iData);					//当当前的节点不为空的时候,输出节点的值
    					localStack.push(temp.leftChild);				//入栈globalStack的左孩子到下一层
    					localStack.push(temp.rightChild);			//入栈globalStack的右孩子到下一层
    					if(temp.leftChild != null || temp.rightChild != null){
    						isRowEmpty = false;								//只要有一个子节点不为空,就把isRowEmpty置为false
    					}
    				}
    				else{																//否则输出--,并把下一层置为空
    					System.out.print("--");
    					localStack.push(null);
    					localStack.push(null);
    				}
    				for(int j=0;j<nBlanks*2-2;j++){
    					System.out.print(' ');
    				}
    			}
    			
    			System.out.println();
    			nBlanks /= 2;													//输出的空格数减半
    			while(localStack.isEmpty() == false){
    				globalStack.push(localStack.pop());			//还原本来的层
    			}
    		}
    		System.out.println(".............................................");
    	}
    	
    	public void preOrder(Node localRoot){			//前序遍历
    		if(localRoot != null){
    			System.out.print(localRoot.iData+" ");
    			preOrder(localRoot.leftChild);
    			preOrder(localRoot.rightChild);
    		}
    	}
    	
    	public void inOrder(Node localRoot){				//中序遍历
    		if(localRoot != null){
    			inOrder(localRoot.leftChild);
    			System.out.print(localRoot.iData+" ");
    			inOrder(localRoot.rightChild);
    		}
    	}
    	
    	public void postOrder(Node localRoot){			//后序遍历
    		if(localRoot != null){
    			postOrder(localRoot.leftChild);
    			postOrder(localRoot.rightChild);
    			System.out.print(localRoot.iData+" ");
    		}
    	}
    	
    	public Node minimum(){				//找到最小的节点
    		Node current;
    		Node last = null;
    		current = root;
    		while(current != null){
    			last = current;
    			current = current.leftChild;
    		}
    		return last;
    	}
    	
    	public Node maxmum(){				//找到最大的节点
    		Node current;
    		Node last = null;
    		current = root;
    		while(current != null){
    			last = current;
    			current = current.rightChild;
    		}
    		return last;
    	}
    	
    	public boolean delete(int key){
    		Node current = root;
    		Node parent = root;
    		boolean isLeftChild = true;
    		
    		while(current.iData != key){//查找要删除的节点,并把其置为current,如果没有返回null
    			parent = current;
    			if(key<current.iData){
    				current = current.leftChild;
    				isLeftChild = true;			//当前current节点的parent节点有左孩子节点
    			}else{
    				current = current.rightChild;
    				isLeftChild = false;			//当前current节点的parent节点没有左孩子节点
    			}
    			if(current == null){
    				return false;
    			}
    		}
    		//进入以下的时候,说明current已经匹配到要删除的节点
    		//如果匹配的current节点没有孩子节点
    		if(current.leftChild == null && current.rightChild == null){
    			if(current == root){		//如果这个节点就是根节点
    				root = null;
    			}else if(isLeftChild){
    				parent.leftChild = null;		//父节点断开左孩子节点
    			}else{
    				parent.rightChild = null;	//父节点断开右孩子节点
    			}
    		}
    		//如果current没有右孩子,则要把左子树上移
    		else if(current.rightChild == null){	
    			if(current == root){							//如果是根节点
    				root = current.leftChild;
    			}else if(isLeftChild){	//如果current节点是左孩子,则把current的左孩子放到parent的左孩子位置
    				parent.leftChild = current.leftChild;
    			}else{								//如果current节点是右孩子,则把current的左孩子放到parent的右孩子位置
    				parent.rightChild = current.leftChild;
    			}
    		}
    		//如果current没有左孩子,则要把右子树上移
    		else if(current.leftChild == null){	
    			if(current == root){							//如果是根节点
    				root = current.rightChild;
    			}else if(isLeftChild){	//如果current节点是左孩子,则把current的右孩子放到parent的左孩子位置
    				parent.leftChild = current.rightChild;
    			}else{								//如果current节点是右孩子,则把current的右孩子放到parent的右孩子位置
    				parent.rightChild = current.rightChild;
    			}
    		}
    		//如果current有左右孩子
    		else{
    			Node successor = getSuccessor(current);
    			if(current == root){		//如果要删除的节点是根节点
    				root = successor;
    			}else if(isLeftChild){		//如果要删除的节点是左孩子
    				parent.leftChild  = successor;
    			}else{									//如果要删除的节点是右孩子
    				parent.rightChild  = successor;
    			}
    			successor.leftChild = current.leftChild;//把最小的值的节点连接到要删除节点的左子树上
    		}
    		return true;
    	}
    	
    	private Node getSuccessor(Node delNode){
    		Node successorParent = delNode;
    		Node successor = delNode;
    		Node current = delNode.rightChild;
    		while(current != null){							//循环,直到返回右子树中最小的值
    			successorParent = successor;
    			successor = current;
    			current = current.leftChild;
    		}
    		if(successor != delNode.rightChild){
    			successorParent.leftChild = successor.rightChild;	//把最小的值的右孩子放到该最小值的位置
    			successor.rightChild = delNode.rightChild;				//把最小的值连接到要删除的节点的右子树上
    		}
    		return successor;
    	}
    		
    }
    
    //主类
    //Function        : 	BinaryTree
    public class BinaryTree {
    
    	public static void main(String[] args) throws Exception{
    		// TODO 自动生成的方法存根
    		int value;
    		Tree theTree = new Tree();
    		theTree.insert(50, 1.5);
    		theTree.insert(25, 1.4);
    		theTree.insert(75, 1.3);
    		theTree.insert(12, 1.6);
    		theTree.insert(37, 1.7);
    		//theTree.insert(43, 1.2);
    		theTree.insert(60, 1.1);
    		theTree.insert(85, 1.1);
    		theTree.insert(77, 1.1);
    		theTree.displayTree();
    		
    		System.out.println("查找节点的值:"+theTree.find(77).iData);
    		
    		theTree.preOrder(theTree.root);
    		System.out.println();
    		theTree.inOrder(theTree.root);
    		System.out.println();
    		theTree.postOrder(theTree.root);
    		System.out.println();
    		System.out.println("最小的节点:"+theTree.minimum().iData);
    		System.out.println("最大的节点:"+theTree.maxmum().iData);
    		
    		theTree.delete(75);
    		theTree.displayTree();
    	}
    
    }
    
  • 相关阅读:
    Hibernate Tomcat JNDI数据源配置(转)
    使用Spring的@Autowired 实现DAO, Service, Controller三层的注入(转)
    丢弃重口味的xml配置--spring4用groovy配置bean(转)
    Java 对象的生命周期
    设计模式学习总结(23) 中介者模式
    WebSocket初探
    设计模式 之 建造者
    谈谈CListCtrl 扩展风格设置方法-SetExtendedStyle和ModifyStyleEx 比較
    linux signal 处理
    UVA 1546
  • 原文地址:https://www.cnblogs.com/tonglin0325/p/5379021.html
Copyright © 2011-2022 走看看