二叉查找树(二叉排序树)的链式实现
2011-05-14 01:10
615 查看
在二叉树里,提到过,并没有去实现插入(只有在指定位置插入),删除操作,因为对于树形结构,跟线性结构不一样,插入没有固定的位置,删除会导致树的形状发生改变。
二叉排序树是在二叉树的基础上,对结点元素增添了有序(Comparable)特性。递归的有: 左子节点 < 根节点 < 右子节点,这样插入就有了唯一的位置,删除导致树形结构的破坏也有规则来重新调整树的结构。
1,二叉查找树的接口ADT
一般来说,二叉排序树要实现下列操作:
LinkedBinarySearchTree
在main函数里构造了如下二叉排序树:
旧金山大学计算机系弄了一个在线的可视化数据结构模拟,前几天google推荐给我的,感觉非常好,国内咋就没有这么好的东西呢,这个图是在那生成的,省去了我许多画图的麻烦,http://www.cs.usfca.edu/~galles/visualization/Algorithms.html
测试结果:
中序遍历结果为:
3 5 6 7 8 9 10 11 13 16 20 25
前序遍历结果为:
10 5 3 7 6 9 8 13 11 20 16 25
后序遍历结果为:
3 6 8 9 7 5 11 16 25 20 13 10
最小元素为: 3
最大元素为: 25
删除最小元素3后的前序序列:
10 5 7 6 9 8 13 11 20 16 25
接着删除最小元素5后的前序序列:
10 7 6 9 8 13 11 20 16 25
二叉排序树是在二叉树的基础上,对结点元素增添了有序(Comparable)特性。递归的有: 左子节点 < 根节点 < 右子节点,这样插入就有了唯一的位置,删除导致树形结构的破坏也有规则来重新调整树的结构。
1,二叉查找树的接口ADT
一般来说,二叉排序树要实现下列操作:
LinkedBinarySearchTree
package Tree; import java.util.Iterator; //继承自二叉树,增添了parent指针,维护一个节点的父节点 public class BinarySearchTree extends BinaryTree implements BinarySearchTreeADT{ //private int count; //private BinaryTreeNode root; //只用到了两个构造函数,因为在二叉查找树里我们已经定义了顺序属性的addElement操作 public BinarySearchTree() { super(); } public BinarySearchTree(Comparable element) { super(element); } //扩展的操作 public void addElement(Comparable element) {//添加节点 BinaryTreeNode temp = new BinaryTreeNode(element); if(root == null) { root = temp; root.parent = null; } else { BinaryTreeNode current = root;//用current来找插入到的那个结点 boolean added = false; while(!added) { if(element.compareTo(current.element) < 0)//比当前节点小 if(current.left == null) { current.left = temp; current.left.parent = current; added = true; }else current = current.left; else //比当前节点大 if(current.right == null) { current.right = temp; current.right.parent = current; added = true; }else current = current.right; } } count++; } public Comparable removeElement(Comparable target) {//删除节点 Comparable result = null; if(!isEmpty()) { if(root.element.equals(target))//如果要删的是根节点 { result = (Comparable) root.element; if(root.left == null && root.right == null) root = null; else if(root.left != null && root.right == null) root = root.left;//注意这里可以直接引用赋值,因为没有右子树,root就是指向左节点了 else if(root.right != null && root.left == null) root = root.right; else { BinaryTreeNode temp = root.left;//找直接前驱 while(temp.right != null) temp = temp.right; root.element = temp.element;//直接前驱赋值到root //root = temp;错 引用赋值,事实上这样root就指向了原来temp的位置 if(temp.left == null) { if(temp.parent != root) temp.parent.right = null; else root.left = null; } else{ temp.element = temp.left.element; temp.left = null; } } count--; } else//否则不是根节点,要先找到删除的节点 { BinaryTreeNode current = root;//current来找删除的节点 boolean found = false; if(target.compareTo(root.element) < 0) current = root.left; else current = root.right; while(current != null && !found) { if(current.element.equals(target))//找到了要删的current { result = (Comparable) current.element; found = true;//如果找到了就改变while循环的found条件,退出循环 count--; //删除节点后的调整!!! if(current == current.parent.left) { if(current.left == null && current.right == null) current.parent.left = null; else if(current.left !=null && current.right == null) current.parent.left = current.left; else if(current.right != null && current.left == null) current.parent.left = current.right; else { BinaryTreeNode temp = current.left;//找直接前驱 while(temp.right != null) temp = temp.right; current.element = temp.element; if(temp.left == null) { if(temp.parent != current) temp.parent.right = null; else current.left = null; } else{ temp.element = temp.left.element; temp.left = null; } } } else { if(current.left == null && current.right == null) current.parent.right = null; else if(current.left !=null && current.right == null) current.parent.right = current.left; else if(current.right != null && current.left == null) current.parent.right = current.right; else { BinaryTreeNode temp = current.left;//找直接前驱 while(temp.right != null) temp = temp.right; current.element = temp.element; if(temp.left == null) { if(temp.parent != current) temp.parent.right = null; else current.left = null; } else{ temp.element = temp.left.element; temp.left = null; } } } } else//否则如果没有找到的话,继续往下找,在这改变while循环的current条件,继续循环 { if(target.compareTo(current.element) < 0) current = current.left; else current = current.right; } } if(!found) { System.out.println("没有找到要删除的元素"); return null; } } } return result; } public Comparable findMax() { if(isEmpty()) { System.out.println("树为空!!!"); return null; } BinaryTreeNode temp = root; while(temp.right != null) temp = temp.right; return (Comparable) temp.element; } public Comparable findMin() { if(isEmpty()) { System.out.println("树为空!!!"); return null; } BinaryTreeNode temp = root; while(temp.left != null) temp = temp.left; return (Comparable) temp.element; } public Comparable removeMax() { if(isEmpty()) { System.out.println("树为空!!!"); return null; } BinaryTreeNode temp = root; while(temp.right != null) temp = temp.right; Comparable result = (Comparable) temp.element; if(temp == root) root = null; else { if(temp.left == null) temp.parent.right = null; else temp.parent.right = temp.left; //{ //temp.element = temp.left.element; //temp.left = null; //} } count--; return result; } public Comparable removeMin() { if(isEmpty()) { System.out.println("树为空!!!"); return null; } BinaryTreeNode temp = root; while(temp.left != null) temp = temp.left; Comparable result = (Comparable) temp.element; if(temp == root) root = null; else { if(temp.right == null) temp.parent.left = null; //temp = null;//错误 同下 else temp.parent.left = temp.right;//不是赋值,是要把temp的右子树和temp的parent连起来 //temp = temp.right;//错误 temp是个局部变量!!!! } count--; return result; } public static void main(String[] args) { BinarySearchTree tree = new BinarySearchTree(); //二叉排序树的形状跟插入顺序有关,中序序列总是不变(有序) tree.addElement(10); tree.addElement(5); tree.addElement(3); tree.addElement(7); tree.addElement(6); tree.addElement(9); tree.addElement(8); tree.addElement(13); tree.addElement(11); tree.addElement(20); tree.addElement(25); tree.addElement(16); System.out.println("\n中序遍历结果为: "); Iterator it = tree.iteratorInorder(); while(it.hasNext()) System.out.print(it.next() + " "); System.out.println("\n前序遍历结果为: "); it = tree.PreInorder(); while(it.hasNext()) System.out.print(it.next() + " "); System.out.println("\n后序遍历结果为: "); it = tree.PostInorder(); while(it.hasNext()) System.out.print(it.next() + " "); System.out.println("\n\n" + "最小元素为: " + tree.findMin()); System.out.println("\n" + "最大元素为: " + tree.findMax()); tree.removeMin(); System.out.println("\n删除最小元素3后的前序序列: "); it = tree.PreInorder(); while(it.hasNext()) System.out.print(it.next() + " "); tree.removeMin(); System.out.println("\n\n接着删除最小元素5后的前序序列: "); it = tree.PreInorder(); while(it.hasNext()) System.out.print(it.next() + " "); //tree.removeElement(10); //tree.removeElement(9); //tree.removeElement(13); //tree.removeElement(10); //tree.removeElement(5); //System.out.println("\n\n删除节点后前序遍历结果为: "); //it = tree.PreInorder(); //while(it.hasNext()) //System.out.print(it.next() + " "); } }
在main函数里构造了如下二叉排序树:
旧金山大学计算机系弄了一个在线的可视化数据结构模拟,前几天google推荐给我的,感觉非常好,国内咋就没有这么好的东西呢,这个图是在那生成的,省去了我许多画图的麻烦,http://www.cs.usfca.edu/~galles/visualization/Algorithms.html
测试结果:
中序遍历结果为:
3 5 6 7 8 9 10 11 13 16 20 25
前序遍历结果为:
10 5 3 7 6 9 8 13 11 20 16 25
后序遍历结果为:
3 6 8 9 7 5 11 16 25 20 13 10
最小元素为: 3
最大元素为: 25
删除最小元素3后的前序序列:
10 5 7 6 9 8 13 11 20 16 25
接着删除最小元素5后的前序序列:
10 7 6 9 8 13 11 20 16 25
相关文章推荐
- 链式结构实现二叉查找树(二叉排序树)
- Java实现链式存储的二叉查找树(递归方法)
- 二叉查找树(二叉排序树)的详细实现
- 二叉查找树(二叉排序树)的详细实现,以及随机平衡二叉查找树Treap的分析与应用
- 二叉查找树(二叉排序树)的详细实现
- 二叉查找树(二叉排序树、有序二叉树)算法分析及实现
- 二叉查找树(二叉排序树)的详细实现
- BST(Binary Search Tree,二叉查找树,二叉排序树)c的实现(部分函数不知如何调用)
- 二叉搜索树(二叉查找树、二叉排序树)及其实现
- 二叉查找树(二叉排序树)的详细实现
- 二叉查找树(二叉排序树)的详细实现
- 二叉查找树(二叉排序树)的详细实现 .
- 数据结构(java语言描述)-- 二叉查找树的链式存储结构的实现
- 二叉查找树(二叉排序树)的详细实现
- 二分查找,二叉查找树(二叉排序树)的基本思想以及算法实现
- 二叉查找树(二叉排序树)的详细实现C版
- 二叉查找树(二叉排序树)的详细实现 .
- 二叉查找树(二叉排序树)的详细实现
- 二叉排序树(二叉查找树)的各种操作C++最新实现
- 二叉查找树(二叉排序树)的详细实现(BST)