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();
    	}
    
    }
    
  • 相关阅读:
    BZOJ 3205 [Apio2013]机器人 ——斯坦纳树
    BZOJ 3782 上学路线 ——动态规划 Lucas定理 中国剩余定理
    HDU 1423 Greatest Common Increasing Subsequence ——动态规划
    BZOJ 3309 DZY Loves Math ——莫比乌斯反演
    POJ 1038 Bugs Integrated, Inc. ——状压DP
    POJ 3693 Maximum repetition substring ——后缀数组
    POJ 2699 The Maximum Number of Strong Kings ——网络流
    POJ 2396 Budget ——有上下界的网络流
    BZOJ 4650 [Noi2016]优秀的拆分 ——后缀数组
    源码安装python
  • 原文地址:https://www.cnblogs.com/tonglin0325/p/5379021.html
Copyright © 2011-2022 走看看