内容有点多,建议先收藏
目录
一.树的介绍
二.java代码实现树
1.Node类
2.Tree类
3.查找节点
4.插入节点
5.遍历树
5.1 中序遍历
5.2 前序遍历和后序遍历
6.查找最大值和最小值
7.删除节点
7.1 删除没有子节点的节点
7.2 删除有一个子节点的结点
7.3 删除有两个节点的节点
8. 完整的二叉树java代码
一.树的介绍
树由边连接的节点而组成,在图中用圆表示节点,实现表示边
路径:顺着节点从一个节点到另一个节点的顺序叫做路径
根:树顶端的节点叫根
父节点:连接下层节点的上层节点称为父节点,例如B是C,D的父节点
子节点:和父节点相连接的节点
叶节点:没有子节点的节点
二.java代码实现树
1.Node类
Node类是节点对象的类,包含了对象的数据
Node类的实现:
class Node{
int iData; //节点的键
double fData; //数据
Node leftChild; //左节点
Node rightChild; //右节点
}
Node类对象还可以指向一个代表数据类型的对象,而不是把数据项直接放在节点中:
class Node{
person p1;
Node leftChild;
Node rightChild;
}
class person{
int iData;
double fData;
}
2.Tree类
Tree类是一个数本身的类,Tree类中有查询,删除,插入以及遍历和显示的方法
Tree类的骨架:
class Tree{
private Node root; //根节点
public void insert(int id,double dd){
}
public void find(int key){
}
public void delete(int id){
}
//.......
}
3.查找节点
规定父节点的左节点小于父节点,右节点小于父节点,在查找是,最先和父节点比较,如果查找的对象小父节点就在父节点的左节点查找,反之在右节点查找,如此类推,直到找到
查找代码:
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;
}
4.插入节点
插入节点,先查找到插入节点的父节点,如果插入的值大于父节点就插入到右节点,反之插入左节点
插入操作代码:
public void insert(int id,double dd){
Node newNode=new Node();
newNode.iData=id;
newNode.dData=dd;
if (root==null)
root=newNode;
else {
Node current=root;
Node parent;
while (true){
parent=current;
if(id<current.iData){
current=current.leftChild;
if (current==null){
parent.leftChild=newNode;
return;
}
else {
current=current.rightChild;
if (current==null){
parent.leftChild=newNode;
return;
}
}
}
}
}
}
5.遍历树
遍历树就是按顺序访问树的每一个节点,遍历有分为中序遍历,前序遍历和后序遍历
5.1 中序遍历
图解中序遍历:
从节点开始沿左边画路径线,当路径线结果节点正下方时该结点被遍历,如图遍历结果:20,30,40,50,60
中序遍历代码:
public void inOrder(Node localRoot){
if (localRoot!=null){
inOrder(localRoot.leftChild);
System.out.print(localRoot.iData+" ");
inOrder(localRoot.rightChild);
}
}
5.2 前序遍历和后序遍历
前序遍历和后序遍历的方法类似于中序遍历
6.查找最大值和最小值
二叉树查找最小值只要遍历左子树,遍历的最后一个就是最小的,反之,遍历右子树,最后一个就是最大的
如·图是查找最小值,查找最小值代码:
public Node minmum(){
Node current,last;
current=root;
while (current!=null){
last=current;
current=current.leftChild;
}
return last;
}
查找最大值:
public Node minmum(){
Node current,last;
current=root;
while (current!=null){
last=current;
current=current.rightChild;
}
return last;
}
7.删除节点
删除节点只要让该节点为null就可以了,虽然该节点依然存在,但java的垃圾回收处理会清除该节点,实现删除节点,删除操作要考虑三种情况:
1.该节点是叶节点
2.该节点有一个子节点
3.该节点有两个子节点
7.1 删除没有子节点的节点
删除没有叶节点,只要改变其父节点对应的子节点的值即可
代码:
public boolean delete(int key){
Node current=root;
Node parent=root;
boolean isLeftChild=true;
while (current.iData!=key){
parent=current;
if(key<current.iData){
isLeftChild=true;
current=current.leftChild;
}
else {
isLeftChild=false;
current=current.rightChild;
}
if(current==null)
return false;
}
if (current.leftChild==null&¤t.rightChild==null){ //如果是叶节点
if (current==root)
root=null;
else if(isLeftChild)
parent.leftChild=null;
else parent.rightChild=null;
}
return true;
}
7.2 删除有一个子节点的结点
删除有一个子节点时,只要将该节点的子节点和其父节点连接即可
部分代码:
else if(current.rightChild==null)
if (current==root)
root=current.leftChild;
else if(isLeftChild)
parent.leftChild=current.rightChild;
else if(current.leftChild==null)
if(current==root)
root=current.rightChild;
else if(isLeftChild)
parent.leftChild=current.rightChild;
else
parent.rightChild=current.rightChild;
7.3 删除有两个节点的节点
删除有两个节点的节点,要找到一个结点和父节点连接,同时该连接的结点要满足大于删除节点的左节点,小于删除节点的右节点,我们称该点为后继点
查找后继点的代码:
public 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;
}
8. 完整的二叉树java代码
public class Mains {
public static void main(String[] args){
Tree tree=new Tree();
tree.insert(3,23);
tree.insert(2,56);
tree.insert(1,43);
tree.insert(7,58);
tree.insert(9,49);
tree.insert(12,62);
tree.insert(4,93);
tree.insert(5,24);
tree.displayTree();
Node node=tree.find(5);
System.out.println("第五个是:"+node.dData);
System.out.println("1.前序遍历,2.中序遍历,3.后序遍历");
tree.traverse(1);
tree.traverse(2);
tree.traverse(3);
tree.delete(7);
System.out.println("删除第7个后:");
tree.displayTree();
}
}
class Node{ //节点
public int iData;
public double dData;
public Node leftChild;
public Node rightChild;
public void display(){
System.out.print("{");
System.out.print(iData);
System.out.print(",");
System.out.print("}");
}
}
class Tree{ //树结构
private 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; //如果找到,返回current
}
//插入操作
public void insert(int id,double dd){
Node newNode=new Node();
newNode.iData=id;
newNode.dData=dd;
if(root==null) //如果根节点为空
root=newNode;
else {
Node current=root; //遍历开始位置
Node parent;
while (true){
parent=current;
if(id<current.iData){ //小于当前二叉树键,在左子树插入
current=current.leftChild;
if (current==null){ //插入左子树最后一个
parent.leftChild=newNode;
return;
}
}else { //目标键大于时,在右子树插入
current=current.rightChild;
if (current==null){ //插入到右子树最后一个
parent.rightChild=newNode;
return;
}
}
}
}
}
//删除操作
public boolean delete(int key){
Node current=root;
Node parent=root;
boolean isleftChild=true;
while (current.iData!=key) {
parent = current; //设置父节点
if (key < current.iData) { //左边操作
isleftChild = true; //表示删除的节点在左节点上
current = current.leftChild;
} else { //右边查找
isleftChild = false;
current = current.rightChild;
}
if (current == null) //如果没有找到要删除的key
return false;
}
//叶节点的删除操作
if(current.leftChild==null&¤t.rightChild==null){
if (current==root) //如果该叶节点为根
root=null;
else if (isleftChild) //如果删除的是左节点
parent.leftChild=null; //删除操作
else
parent.rightChild=null; //删除操作
}
//有一个节点的删除操作
else if (current.rightChild==null) //只有一个左节点
if (current==root)
root=current.leftChild;
else if (isleftChild) //如果删除的是左节点
parent.leftChild=current.leftChild; //该删除节点的左节点连接该父节点
else
parent.rightChild=current.leftChild; 该删除节点的右节点连接该父节点
else if (current.leftChild==null) //只有一个右节点
if (current==root)
root=current.rightChild;
else if (isleftChild)
parent.leftChild=current.rightChild;
else
parent.rightChild=current.rightChild;
else { //有两个节点的删除,先找后继点
Node successor = getSuccessor(current); //调用getSuccessor寻找后继点
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;
}
//选择遍历方式操作
public void traverse(int travesType){
switch (travesType){
case 1:System.out.print("前序遍历:");
preOrder(root);
break;
case 2:System.out.print("中序遍历:");
inOrder(root);
break;
case 3:System.out.print("后序遍历:");
postOrder(root);
break;
}
System.out.println(" ");
}
//前序遍历
private void preOrder(Node locaRoot){
if(locaRoot!=null){
System.out.print(locaRoot.iData+" ");
preOrder(locaRoot.leftChild);
preOrder(locaRoot.rightChild);
}
}
//中序遍历
private void inOrder(Node locaRoot){
if (locaRoot!=null){
inOrder(locaRoot.rightChild);
System.out.print(locaRoot.iData+" ");
inOrder(locaRoot.leftChild);
}
}
//后序遍历
private void postOrder(Node locaRoot){
if (locaRoot!=null){
postOrder(locaRoot.leftChild);
postOrder(locaRoot.rightChild);
System.out.print(locaRoot.iData+" ");
}
}
//显示操作
public void displayTree(){
Stack globalStack=new Stack();
globalStack.push(root);
int nBlank=32;
boolean isRowEmpty=false;
System.out.println("---------------------------------------");
while (isRowEmpty==false){
Stack localStack=new Stack();
isRowEmpty=true;
for (int j=0;j<nBlank;j++)
System.out.print(" ");
while (globalStack.isEmpty()==false){
Node temp=(Node)globalStack.pop();
if(temp!=null){
System.out.print(temp.iData);
localStack.push(temp.leftChild);
localStack.push(temp.rightChild);
if (temp.leftChild!=null || temp.rightChild!=null)
isRowEmpty=false;
}else {
System.out.print("--");
localStack.push(null);
localStack.push(null);
}
for (int i=0;i<nBlank*2-2;i++)
System.out.print(" ");
}
System.out.println( );
nBlank/=2;
while (localStack.isEmpty()==false)
globalStack.push(localStack.pop());
}
System.out.println("-------------------------------");
}
}
运行: