跟小刀学习 数据结构二叉树的实现
2017-05-03 21:44
295 查看
最近学习的有点累。导致二叉树学习的有点模糊
我们之前学过数组 和链表 数组插入比较慢 链表查询比较慢。这时候我们就需要使用树这种结构。都比较快
树的基本概念
根:树最上面的节点称为根节点,一棵树只有一个根节点
父节点:每一个节点都有一条边向上连接到另一个节点,这个节点就是称为下面这个节点的父节点
子节点:每一个节点都有条向下连接的节点,下面的这个节点就是该节点的子节点
叶子节点:没有子节点的节点也叫叶子节点.
子树:每一个节点都可以作为一个子树的根。他和他的所有子节点组合在一起就是个子树
查找节点:从根节点开始查找,如果查找的节点值比当前节点的值小,则继续查找左子树,否则查找右子树
遍历树:遍历树是根据一个特定的顺序访问树的每一个节点,根据顺序的不同分为前序,中序,后序遍历三种。
前序遍历。
(1)访问根节点
(2)前序遍历左子树
(3)前序遍历右子树
中序遍历。
(1)中序遍历左子树
(2)访问根节点
(3)中序遍历右子树
后序遍历。
(1)后序遍历左子树
(2)后序遍历右子树
(3)访问根节点
上代码:
二叉树的具体实现
测试代码:
至于测试结果我就不贴了。很多。在删除二叉树有俩个节点的时。我没有弄明白。我先贴代码。最近比较累。
我们之前学过数组 和链表 数组插入比较慢 链表查询比较慢。这时候我们就需要使用树这种结构。都比较快
树的基本概念
根:树最上面的节点称为根节点,一棵树只有一个根节点
父节点:每一个节点都有一条边向上连接到另一个节点,这个节点就是称为下面这个节点的父节点
子节点:每一个节点都有条向下连接的节点,下面的这个节点就是该节点的子节点
叶子节点:没有子节点的节点也叫叶子节点.
子树:每一个节点都可以作为一个子树的根。他和他的所有子节点组合在一起就是个子树
查找节点:从根节点开始查找,如果查找的节点值比当前节点的值小,则继续查找左子树,否则查找右子树
遍历树:遍历树是根据一个特定的顺序访问树的每一个节点,根据顺序的不同分为前序,中序,后序遍历三种。
前序遍历。
(1)访问根节点
(2)前序遍历左子树
(3)前序遍历右子树
中序遍历。
(1)中序遍历左子树
(2)访问根节点
(3)中序遍历右子树
后序遍历。
(1)后序遍历左子树
(2)后序遍历右子树
(3)访问根节点
上代码:
/** * 二叉树的节点类 * @author Administrator * */ public class Node { public int iData; public String sData; public Node leftChild; public Node rightChild; public Node(int iData,String sData) { this.iData = iData; this.sData =sData; } public Node() { // TODO Auto-generated constructor stub } public void dispalyNode(){ 4000 System.out.print("{"+ iData +"}"); } }
二叉树的具体实现
package com.chapter5_1; public class Tree { //根节点 public Node root; /** * 二叉树的插入 s */ public void insert(int d,String s){ //新节点 Node newNode = new Node(d,s); //引用当前的节点 Node current = root; //引用父节点 Node parent; if(current == null){ root = newNode; return ;//如果root节点为空的话,直接点添加都结束了 } while(true){ //先将当前的节点付给一个parent. 这个节点一直在变动 parent = current; if(d < current.iData){ //当前的节点变成刚才的左节点 current = current.leftChild; if(current == null){ parent.leftChild =newNode; return; } }else{//d > // 变成刚才的又节点 current = current.rightChild; if(current == null){ parent.rightChild= newNode; return; } } } } /** * 查找二叉树 * @param value * @return */ public Node find(int value){ Node current = root; while(current.iData !=value){ //如果这个值比当前的节点值小,那么找左子节点 if(current.iData > value){ current = current.leftChild; }else{ current = current.rightChild; } if(current == null){ return null; } } return current; } public void traverse(int traverseType){ switch (traverseType) { case 1:// //前序遍历 System.out.println("前序遍历"); frontOrder(root); break; case 2: System.out.println("中序遍历"); inOrder(root); break; case 3: System.out.println("后序遍历"); postOrder(root); break; default: break; } System.out.println("--------------------------------"); } /** * 前序遍历 * @param localNode */ public void frontOrder(Node localNode){ if(localNode != null){ //访问根节点 System.out.println(localNode.iData +","+localNode.sData); //前序遍历左子树 frontOrder(localNode.leftChild); //前序遍历右子树 frontOrder(localNode.rightChild); } } /** * 中序遍历 - * 1.中序遍历左子树 * 2.访问根节点 * 3.中序遍历右子树(从小到大) * @param localNode */ public void inOrder(Node localNode){ if(localNode != null){ //中序遍历左子树 inOrder(localNode.leftChild); //访问根节点 System.out.println(localNode.iData +","+localNode.sData); //中序遍历右子树 inOrder(localNode.rightChild); } } /** * 后序遍历。。先遍历左子树-右子树-访问根节点 * @param localNode */ public void postOrder(Node localNode){ if(localNode != null){ //后序遍历左子树 postOrder(localNode.leftChild); //后序遍历右子树 postOrder(localNode.rightChild); //访问根节点 System.out.println(localNode.iData +","+localNode.sData); } } /** * 删除一个节点 * 有3种情况 * 1.该节点是叶子节点 * 2.该节点只有 一个节点 * 3.该节点有俩个节点。需要找到右边节点的最小节点。(中序遍历后继。。找到) * @param value * @return */ public boolean delete(int value){ //引用当前节点 Node current = root; //引用父节点 Node parent = root; //判断是否为左子节点 boolean isLeftChild =true; while(current.iData != value){ //先赋值 parent = current; //如果这个值比当前的节点值小,那么找左子节点 if(current.iData > value){ current = current.leftChild; isLeftChild =true; }else{ current = current.rightChild; isLeftChild =false; } if(current == null){ return false; } } //删除叶子节点,也就是该节点没有子节点 if(current.leftChild == null && current.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); if(current ==root){ root = successor; }else if(isLeftChild){ parent.leftChild = successor; }else{ parent.rightChild = successor; } successor.leftChild =current.leftChild; } return true; } public Node getSuccessor(Node delNode){ Node successor = delNode; Node successorParent = 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; } }
测试代码:
package com.chapter5_1; public class Test { public static void main(String[] args) { Tree t = new Tree(); t.insert(10,"thinkpad"); t.insert(20,"mac"); t.insert(15,"del"); t.insert(3,"leishen"); t.insert(40,"zhangsan"); t.insert(16,"liao"); t.insert(4,"luyao"); // System.out.println(t.root.rightChild.iData); // System.out.println(t.root.rightChild.leftChild.iData); // System.out.println(t.root.leftChild.iData); // Node node = t.find(15); //// System.out.println(node.iData +", " + node.sData); // node = t.find(3); //// System.out.println(node.iData +", " + node.sData); t.delete(3); // t.traverse(1); t.traverse(2); // t.traverse(3); t.delete(16); // t.traverse(1); t.traverse(2); } }
至于测试结果我就不贴了。很多。在删除二叉树有俩个节点的时。我没有弄明白。我先贴代码。最近比较累。
相关文章推荐
- 数据结构 学习笔记之:顺序栈的C语言实现
- 数据结构与算法(C#实现)系列---二叉树
- 数据结构 学习笔记之:静态链表--史上最简单的C语言实现——只为掌握概念——不清楚静态链表的鸟鸟们有福了!
- 数据结构——二叉树 前序、中序、后序、层次遍历及非递归实现 查找、统计个数、比较、求深度的递归实现
- 【算法学习笔记】08.数据结构基础 二叉树初步练习1
- 【算法学习笔记】10.数据结构基础 二叉树初步练习3(遍历与递归复习)
- 数据结构(六)——二叉树 前序、中序、后序、层次遍历及非递归实现 查找、统计个数、比较、求深度的递归实现
- 【算法学习笔记】09.数据结构基础 二叉树初步练习2
- 数据结构之二叉树实现
- 算法与数据结构基础4:C++二叉树实现及遍历方法大全
- 数据结构之二叉树的非递归实现及“狡猾”的指针
- 数据结构(六)——二叉树 前序、中序、后序、层次遍历及非递归实现 查找、统计个数、比较、求深度的递归实现
- 数据结构与算法学习笔记——链表部分实现(数组形式)
- 数据结构——二叉树的链式实现(C语言)
- 【算法学习笔记】09.数据结构基础 二叉树初步练习2
- 数据结构与算法(C#实现)系列---二叉树
- C#实现二叉树数据结构以及先序、中序、后续遍历
- java 二叉树 实现 数据结构 笔试
- 数据结构与实现——数组、矩阵、链表、队列、栈、对象、二叉树和红黑树
- 【算法学习笔记】11.数据结构基础 二叉树初步练习4