087-089 哈希表
087 哈希表实现思路图解
基本介绍: 哈希表的基本介绍(Hash table,也叫哈希表),是根据关键码值(key value)而直接进行访问的数据结构。也就是说,它通过把关键码值映射到表中一个位置来访问记录,以加快查找的速度。这个映射函数叫做散列函数,存放记录的数组叫做散列表。
088-089 哈希表代码实现1-2
package com
.old
.hashTable_087_089
;
import java
.util
.Random
;
import java
.util
.Scanner
;
public class HashTableDemo {
public static void main(String
[] args
) {
HashTable hashTable
= new HashTable(7);
int size
= hashTable
.getSize();
int count
= size
* 2;
Random random
= new Random(count
);
for (int i
= 0; i
< size
; i
++) {
int id
= random
.nextInt();
hashTable
.add(new Emp(id
, id
+ "号"));
}
String key
= "";
Scanner scanner
= new Scanner(System
.in
);
boolean flag
= true;
while (flag
) {
System
.out
.println("1.添加");
System
.out
.println("2.显示");
System
.out
.println("3.退出");
key
= scanner
.nextLine();
try {
switch (key
) {
case "1":
System
.out
.println("输入id");
int id
= scanner
.nextInt();
System
.out
.println("输入名称");
String name
= scanner
.next();
Emp emp
= new Emp(id
, name
);
hashTable
.add(emp
);
break;
case "2":
hashTable
.list();
break;
case "3":
flag
= false;
break;
case "4":
System
.out
.println("输入要查找的id");
id
= scanner
.nextInt();
hashTable
.findEmpById(id
);
break;
}
key
= null
;
System
.out
.println();
} catch (Exception e
) {
e
.printStackTrace();
}
}
scanner
.close();
}
}
class HashTable {
private EmpLinkedList
[] empLinkedListArray
;
private int size
;
public int getSize() {
return size
;
}
public HashTable(int size
) {
this.size
= size
;
empLinkedListArray
= new EmpLinkedList[size
];
for (int i
= 0; i
< size
; i
++) {
empLinkedListArray
[i
] = new EmpLinkedList();
}
}
public void add(Emp emp
) {
int empLinkedListNO
= hashFun(emp
.id
);
EmpLinkedList empLinkedList
= empLinkedListArray
[empLinkedListNO
];
empLinkedList
.add(emp
);
}
public void list() {
for (int i
= 0; i
< empLinkedListArray
.length
; i
++) {
empLinkedListArray
[i
].list( i
+ 1);
}
}
public void findEmpById(int id
){
int empLinkedListNO
= hashFun(id
);
Emp emp
= empLinkedListArray
[empLinkedListNO
].findEmpById(id
);
System
.out
.println("第" + (empLinkedListNO
+ 1) + "条链表中找到: " + emp
);
}
public int hashFun(int id
) {
return id
% size
;
}
}
class Emp {
public int id
;
public String name
;
public Emp next
;
public Emp(int id
, String name
) {
this.id
= id
;
this.name
= name
;
}
@Override
public String
toString() {
return "Emp{" +
"id=" + id
+
", name='" + name
+ '\'' +
'}';
}
}
class EmpLinkedList {
private Emp head
;
public void add(Emp emp
) {
if (head
== null
) {
head
= emp
;
return;
}
Emp curEmp
= this.head
;
while (true) {
if (curEmp
.next
== null
) {
break;
}
curEmp
= curEmp
.next
;
}
curEmp
.next
= emp
;
}
public void list(int no
) {
if (head
== null
) {
System
.out
.println("链表为空");
return;
}
Emp curEmp
= head
;
while (true) {
System
.out
.println("第" + no
+ "条链表,id:" + curEmp
.id
+ "名称:"+ curEmp
.name
);
if (curEmp
.next
== null
) {
break;
}
curEmp
= curEmp
.next
;
}
System
.out
.println();
}
public void mylist() {
if (head
== null
) {
System
.out
.println("链表为空");
return;
}
for (Emp curEmp
= head
; curEmp
!= null
; curEmp
= curEmp
.next
) {
System
.out
.println(curEmp
);
}
}
public void myAdd(Emp emp
) {
if (head
== null
) {
head
= emp
;
return;
}
Emp temp
= this.head
;
while (temp
!= null
) {
temp
= temp
.next
;
}
temp
= emp
;
return;
}
public Emp
findEmpById(int id
){
if (head
== null
){
System
.out
.println("链表为空");
return null
;
}
Emp curEmp
= head
;
while (true){
if (curEmp
.id
== id
){
break;
}
if (curEmp
.next
== null
){
curEmp
= null
;
}
curEmp
= curEmp
.next
;
}
return curEmp
;
}
public Emp
myFindEmpById(int id
){
for (Emp curEmp
= head
; curEmp
!= null
; curEmp
= curEmp
.next
) {
if (curEmp
.id
== id
){
return curEmp
;
}
}
return null
;
}
}
090-106 二叉树
090 数组、链表、树存储方式
二叉树
数组存储方式的分析 优点:通过下标方式访问元素,速度快。对于有序数组,还可使用二分查找提高检索速度。 缺点:如果要检索某个值,或者插入传下(按一定顺序)会整体移动,效率较低
链式存储方式的分析 优点:在一定程度上对数组存储方式有优化(比如:插入一个数值节点,只需要将插入节点,链接到链表中即可,删除效率也很好) 缺点:在进行检索时,效率仍然较低,比如:检索某个值,需要从头节点开始遍历
树存储方式的分析 能提高数据存储,读取的效率,比如利用 **二叉排序树(Binary Sort Tree),既可以保证数据的检索速度,同时可以保证数据的插入,删除,修改的速度)
ArrayList 的底层操作机制源码分析
## 091 二叉树的概念和常用术语 树的常用术语
节点根节点父节点子节点叶子节点(没有子节点的节点)节点的权(节点值)路径(从 root 节点找到该节点的路线)层子树树的高度(最大层度)森林:多颗子树构成森林
二叉树的概念
树有很多种,每个节点最多只能有两个子节点的一种形式称为二叉树二叉树的子节点分为左节点和右节点如果该二叉树的的所有叶子节点都在最后一层,并且结点总数(这里的结点总数,是指所有的结点)=2
n - 1 , n 为层数,则我们称为二叉树如果该二叉树的所有叶子节点都在最后一层或者倒数第二层,而且最后一层的叶子节点在左边连续,倒数第二层的叶子节点在右边连续,我们称为完全二叉树
092 前序中序后序遍历二叉树的图解
前序遍历:先输出父节点,再遍历左子树和右子树 中序遍历:先遍历左子树,再输出父节点,再遍历右子树 后序遍历:先遍历左子树,再遍历右子树,最后输出父节点 小结:看输出父节点的顺序,就确定是前序、中序不是后序
图解
创建一棵二叉树前序遍历
先输出当前节点(初始的时候是root节点)如果左子节点不为空,则递归继续前序遍历如果右子节点不为空,则递归继续前序遍历 中序遍历
如果当前节点的左子节点不为空,则递归继续中序遍历先输出当前节点如果当前节点的右子节点不为空,则递归继续中序遍历 后序遍历
如果当前节点的左子节点不为空,则递归后序遍历如果当前节点的右子节点不为空,则递归后序遍历先输出当前节点
093-094 前序中序后序遍历代码实现
package com
.old
.Tree_90
;
public class BinaryTreeDemo {
public static void main(String
[] args
) {
BinaryTree binaryTree
= new BinaryTree();
HeroNode root
= new HeroNode(1, "宋江");
HeroNode node2
= new HeroNode(2, "吴用");
HeroNode node3
= new HeroNode(3, "卢俊义");
HeroNode node4
= new HeroNode(4, "林冲");
HeroNode node5
= new HeroNode(5, "关胜");
root
.setLeft(node2
);
root
.setRight(node3
);
node3
.setRight(node4
);
binaryTree
.setRoot(root
);
System
.out
.println("前序遍历");
binaryTree
.preOrder();
System
.out
.println();
System
.out
.println("中序遍历");
binaryTree
.infixOrder();
System
.out
.println();
System
.out
.println("后序遍历");
binaryTree
.postOrder();
System
.out
.println();
node3
.setLeft(node5
);
System
.out
.println("前序遍历");
binaryTree
.preOrder();
System
.out
.println();
System
.out
.println("中序遍历");
binaryTree
.infixOrder();
System
.out
.println();
System
.out
.println("后序遍历");
binaryTree
.postOrder();
System
.out
.println();
}
}
class BinaryTree {
private HeroNode root
;
public void setRoot(HeroNode root
) {
this.root
= root
;
}
public void preOrder() {
if (this.root
!= null
) {
root
.preOrder();
} else {
System
.out
.println("二叉树为空,无法遍历");
}
}
public void infixOrder() {
if (this.root
!= null
) {
root
.infixOrder();
} else {
System
.out
.println("二叉树为空,无法遍历");
}
}
public void postOrder() {
if (this.root
!= null
) {
root
.postOrder();
} else {
System
.out
.println("二叉树为空,无法遍历");
}
}
}
class HeroNode {
private int no
;
private String name
;
private HeroNode left
;
private HeroNode right
;
public HeroNode(int no
, String name
) {
this.no
= no
;
this.name
= name
;
}
@Override
public String
toString() {
return "HeroNode{" +
"no=" + no
+
", name='" + name
+ '\'' +
'}';
}
public void setNo(int no
) {
this.no
= no
;
}
public void setName(String name
) {
this.name
= name
;
}
public void setLeft(HeroNode left
) {
this.left
= left
;
}
public void setRight(HeroNode right
) {
this.right
= right
;
}
public int getNo() {
return no
;
}
public String
getName() {
return name
;
}
public HeroNode
getLeft() {
return left
;
}
public HeroNode
getRight() {
return right
;
}
public void preOrder() {
System
.out
.println(this);
if (this.left
!= null
) {
this.left
.preOrder();
}
if (this.right
!= null
) {
this.right
.preOrder();
}
}
public void infixOrder() {
if (this.left
!= null
) {
this.left
.infixOrder();
}
System
.out
.println(this);
if (this.right
!= null
) {
this.right
.infixOrder();
}
}
public void postOrder() {
if (this.left
!= null
) {
this.left
.postOrder();
}
if (this.right
!= null
) {
this.right
.postOrder();
}
System
.out
.println(this);
}
}
095-097 前序中序后序查找
095 思路图解
前序、中序、后序的方式来查询指定的结点
前序查找
先判断当前结点的 no 是否等于要查找的相等,则返回当前结点如果不等于,则判断当前结点的左子节点是否为空,如果不为空,则递归前序查找如果左递归前序查找,找到结点,则返回,否继续判断,当前的结点的右子节点是否为空,如果不空,则继续向右递归查找
中序查找
判断当前结点的左子节点是否为空,如果不为空,则递归中序查找如果找到,则返回,如果没有找到,就和当前结点比较,如果是则返回当前结点,否则继续进行右递归的中序查找如果右递归中序查找,找到就返回,否则返回null
后序查找
判断当前结点的左子节点是否为空,如果不为空,则递归后序查找如果找到,就返回,如果没有找到,就判断当前结点的右子节点是否为空,如果不为空,则右递归进行后序查找,如果找到,就返回就和当前结点进行,比如,如果是则返回,否则返回null
096-097 代码实现
package com
.old
.Tree_90
;
public class BinaryTreeDemo {
public static void main(String
[] args
) {
BinaryTree binaryTree
= new BinaryTree();
HeroNode root
= new HeroNode(1, "宋江");
HeroNode node2
= new HeroNode(2, "吴用");
HeroNode node3
= new HeroNode(3, "卢俊义");
HeroNode node4
= new HeroNode(4, "林冲");
HeroNode node5
= new HeroNode(5, "关胜");
HeroNode node6
= new HeroNode(5, "测试胜");
root
.setLeft(node2
);
root
.setRight(node3
);
node3
.setRight(node4
);
binaryTree
.setRoot(root
);
System
.out
.println("前序遍历");
binaryTree
.preOrder();
System
.out
.println();
System
.out
.println("中序遍历");
binaryTree
.infixOrder();
System
.out
.println();
System
.out
.println("后序遍历");
binaryTree
.postOrder();
System
.out
.println();
node3
.setLeft(node5
);
System
.out
.println("前序遍历");
binaryTree
.preOrder();
System
.out
.println();
System
.out
.println("中序遍历");
binaryTree
.infixOrder();
System
.out
.println();
System
.out
.println("后序遍历");
binaryTree
.postOrder();
System
.out
.println();
int no
= 2;
System
.out
.println(binaryTree
.myPreOrderSearch(no
));
System
.out
.println();
System
.out
.println(binaryTree
.preOrderSearch(no
));
System
.out
.println();
System
.out
.println(binaryTree
.infixOrderSearch(no
));
System
.out
.println();
System
.out
.println(binaryTree
.postOrderSearch(no
));
System
.out
.println();
System
.out
.println("二分查找测试:" + binaryTree
.mySearch(no
));
}
}
class BinaryTree {
private HeroNode root
;
public void setRoot(HeroNode root
) {
this.root
= root
;
}
public void preOrder() {
if (this.root
!= null
) {
root
.preOrder();
} else {
System
.out
.println("二叉树为空,无法遍历");
}
}
public void infixOrder() {
if (this.root
!= null
) {
root
.infixOrder();
} else {
System
.out
.println("二叉树为空,无法遍历");
}
}
public void postOrder() {
if (this.root
!= null
) {
root
.postOrder();
} else {
System
.out
.println("二叉树为空,无法遍历");
}
}
public HeroNode
myPreOrderSearch(int no
) {
if (root
== null
) {
return null
;
} else {
return root
.myPreOrderSearch(no
);
}
}
public HeroNode
mySearch(int no
) {
if (root
== null
) {
return null
;
} else {
return root
.mySearch(no
);
}
}
public HeroNode
preOrderSearch(int no
) {
if (root
== null
) {
return null
;
} else {
return root
.preOrderSearch(no
);
}
}
public HeroNode
infixOrderSearch(int no
) {
if (root
== null
) {
return null
;
} else {
return root
.infixOrderSearch(no
);
}
}
public HeroNode
postOrderSearch(int no
) {
if (root
== null
) {
return null
;
} else {
return root
.postOrderSearch(no
);
}
}
}
class HeroNode {
private int no
;
private String name
;
private HeroNode left
;
private HeroNode right
;
public HeroNode(int no
, String name
) {
this.no
= no
;
this.name
= name
;
}
@Override
public String
toString() {
return "HeroNode{" +
"no=" + no
+
", name='" + name
+ '\'' +
'}';
}
public void setNo(int no
) {
this.no
= no
;
}
public void setName(String name
) {
this.name
= name
;
}
public void setLeft(HeroNode left
) {
this.left
= left
;
}
public void setRight(HeroNode right
) {
this.right
= right
;
}
public int getNo() {
return no
;
}
public String
getName() {
return name
;
}
public HeroNode
getLeft() {
return left
;
}
public HeroNode
getRight() {
return right
;
}
public void preOrder() {
System
.out
.println(this);
if (this.left
!= null
) {
this.left
.preOrder();
}
if (this.right
!= null
) {
this.right
.preOrder();
}
}
public void infixOrder() {
if (this.left
!= null
) {
this.left
.infixOrder();
}
System
.out
.println(this);
if (this.right
!= null
) {
this.right
.infixOrder();
}
}
public void postOrder() {
if (this.left
!= null
) {
this.left
.postOrder();
}
if (this.right
!= null
) {
this.right
.postOrder();
}
System
.out
.println(this);
}
public HeroNode
myPreOrderSearch(int no
) {
System
.out
.println("我的前序遍历");
if (this.no
== no
) {
return this;
}
HeroNode temp
= null
;
if (this.left
!= null
) {
temp
= this.left
.myPreOrderSearch(no
);
}
if (temp
!= null
) {
return temp
;
}
if (this.right
!= null
) {
temp
= this.right
.myPreOrderSearch(no
);
}
return temp
;
}
public HeroNode
preOrderSearch(int no
) {
System
.out
.println("前序遍历");
if (this.no
== no
) {
return this;
}
HeroNode repNode
= null
;
if (this.left
!= null
) {
repNode
= this.left
.preOrderSearch(no
);
}
if (repNode
!= null
) {
return repNode
;
}
if (this.right
!= null
) {
repNode
= this.right
.preOrderSearch(no
);
}
return repNode
;
}
public HeroNode
infixOrderSearch(int no
) {
HeroNode repNode
= null
;
if (this.left
!= null
) {
repNode
= this.left
.infixOrderSearch(no
);
}
if (repNode
!= null
) {
return repNode
;
}
System
.out
.println("中序遍历");
if (this.no
== no
) {
return this;
}
if (this.right
!= null
) {
repNode
= this.right
.infixOrderSearch(no
);
}
return repNode
;
}
public HeroNode
postOrderSearch(int no
) {
HeroNode repNode
= null
;
if (this.left
!= null
) {
repNode
= this.left
.postOrderSearch(no
);
}
if (repNode
!= null
) {
return repNode
;
}
if (this.right
!= null
) {
repNode
= this.right
.postOrderSearch(no
);
}
if (repNode
!= null
) {
return repNode
;
}
System
.out
.println("后序遍历");
if (this.no
== no
) {
return this;
}
return repNode
;
}
public HeroNode
mySearch(int no
) {
HeroNode temp
= null
;
if (this.no
< no
&& this.left
!= null
) {
temp
= this.left
.mySearch(no
);
} else if (this.no
> no
&& this.right
!= null
) {
temp
= this.right
.mySearch(no
);
} else {
return this;
}
return temp
;
}
}
098-099 二叉树删除节点
要删除的节点是叶子节点,则删除该节点如果删除的节点是非叶子节点,则删除该子树测试删除掉5号叶子节点和3号子树
098 思路
思路: 目前先实现整个删除的效果,后续再实现更复杂的删除 是否是空树,如果只有一个 root 结点,则等价将二叉树置空
因为二叉树是单向的,所以是判断当前节点的子节点是否需要删除节点,而不能去判断当前这个节点是不是需要删除节点如果当前节点的左子节点不为空,并且左子节点就是要删除节点,就将 this.left = null; 并且就返回 (结束递归)如果当前节点的右子节点不为空, 并且右子节点就是要删除结点,就将 this.right = null; 并返回如果第二步和第三歩没有删除节点,就需要向左子树递归删除如果第4步也没有删除结点,则应当向右子树进行递归删除如果树是空root,如果只有一个 root 节点,则等价将二叉树置空
二叉树删除节点代码实现
package com
.old
.Tree_90
;
public class BinaryTreeDemo {
public static void main(String
[] args
) {
BinaryTree binaryTree
= new BinaryTree();
HeroNode root
= new HeroNode(1, "宋江");
HeroNode node2
= new HeroNode(2, "吴用");
HeroNode node3
= new HeroNode(3, "卢俊义");
HeroNode node4
= new HeroNode(4, "林冲");
HeroNode node5
= new HeroNode(5, "关胜");
HeroNode node6
= new HeroNode(5, "测试胜");
root
.setLeft(node2
);
root
.setRight(node3
);
node3
.setRight(node4
);
binaryTree
.setRoot(root
);
System
.out
.println("前序遍历");
binaryTree
.preOrder();
System
.out
.println();
System
.out
.println("中序遍历");
binaryTree
.infixOrder();
System
.out
.println();
System
.out
.println("后序遍历");
binaryTree
.postOrder();
System
.out
.println();
node3
.setLeft(node5
);
System
.out
.println("前序遍历");
binaryTree
.preOrder();
System
.out
.println();
System
.out
.println("中序遍历");
binaryTree
.infixOrder();
System
.out
.println();
System
.out
.println("后序遍历");
binaryTree
.postOrder();
System
.out
.println();
int no
= 2;
System
.out
.println(binaryTree
.myPreOrderSearch(no
));
System
.out
.println();
System
.out
.println(binaryTree
.preOrderSearch(no
));
System
.out
.println();
System
.out
.println(binaryTree
.infixOrderSearch(no
));
System
.out
.println();
System
.out
.println(binaryTree
.postOrderSearch(no
));
System
.out
.println();
System
.out
.println("二分查找测试:" + binaryTree
.mySearch(no
));
System
.out
.println();
System
.out
.println("开始删除");
binaryTree
.myRemove(5);
binaryTree
.myRemove(3);
binaryTree
.preOrder();
System
.out
.println();
}
}
class BinaryTree {
private HeroNode root
;
public void setRoot(HeroNode root
) {
this.root
= root
;
}
public void preOrder() {
if (this.root
!= null
) {
root
.preOrder();
} else {
System
.out
.println("二叉树为空,无法遍历");
}
}
public void infixOrder() {
if (this.root
!= null
) {
root
.infixOrder();
} else {
System
.out
.println("二叉树为空,无法遍历");
}
}
public void postOrder() {
if (this.root
!= null
) {
root
.postOrder();
} else {
System
.out
.println("二叉树为空,无法遍历");
}
}
public HeroNode
myPreOrderSearch(int no
) {
if (root
== null
) {
return null
;
} else {
return root
.myPreOrderSearch(no
);
}
}
public HeroNode
mySearch(int no
) {
if (root
== null
) {
return null
;
} else {
return root
.mySearch(no
);
}
}
public void myRemove(int no
) {
if (root
== null
) {
return;
}
if (root
.getNo() == no
){
root
= null
;
return;
}
root
.myRemove(no
);
}
public void delNode(int no
) {
if (root
== null
) {
return;
}
if (root
.getNo() == no
){
root
= null
;
return;
}
root
.delNode(no
);
}
public HeroNode
preOrderSearch(int no
) {
if (root
== null
) {
return null
;
} else {
return root
.preOrderSearch(no
);
}
}
public HeroNode
infixOrderSearch(int no
) {
if (root
== null
) {
return null
;
} else {
return root
.infixOrderSearch(no
);
}
}
public HeroNode
postOrderSearch(int no
) {
if (root
== null
) {
return null
;
} else {
return root
.postOrderSearch(no
);
}
}
}
class HeroNode {
private int no
;
private String name
;
private HeroNode left
;
private HeroNode right
;
public HeroNode(int no
, String name
) {
this.no
= no
;
this.name
= name
;
}
@Override
public String
toString() {
return "HeroNode{" +
"no=" + no
+
", name='" + name
+ '\'' +
'}';
}
public void setNo(int no
) {
this.no
= no
;
}
public void setName(String name
) {
this.name
= name
;
}
public void setLeft(HeroNode left
) {
this.left
= left
;
}
public void setRight(HeroNode right
) {
this.right
= right
;
}
public int getNo() {
return no
;
}
public String
getName() {
return name
;
}
public HeroNode
getLeft() {
return left
;
}
public HeroNode
getRight() {
return right
;
}
public void preOrder() {
System
.out
.println(this);
if (this.left
!= null
) {
this.left
.preOrder();
}
if (this.right
!= null
) {
this.right
.preOrder();
}
}
public void infixOrder() {
if (this.left
!= null
) {
this.left
.infixOrder();
}
System
.out
.println(this);
if (this.right
!= null
) {
this.right
.infixOrder();
}
}
public void postOrder() {
if (this.left
!= null
) {
this.left
.postOrder();
}
if (this.right
!= null
) {
this.right
.postOrder();
}
System
.out
.println(this);
}
public HeroNode
myPreOrderSearch(int no
) {
System
.out
.println("我的前序遍历");
if (this.no
== no
) {
return this;
}
HeroNode temp
= null
;
if (this.left
!= null
) {
temp
= this.left
.myPreOrderSearch(no
);
}
if (temp
!= null
) {
return temp
;
}
if (this.right
!= null
) {
temp
= this.right
.myPreOrderSearch(no
);
}
return temp
;
}
public HeroNode
preOrderSearch(int no
) {
System
.out
.println("前序遍历");
if (this.no
== no
) {
return this;
}
HeroNode repNode
= null
;
if (this.left
!= null
) {
repNode
= this.left
.preOrderSearch(no
);
}
if (repNode
!= null
) {
return repNode
;
}
if (this.right
!= null
) {
repNode
= this.right
.preOrderSearch(no
);
}
return repNode
;
}
public HeroNode
infixOrderSearch(int no
) {
HeroNode repNode
= null
;
if (this.left
!= null
) {
repNode
= this.left
.infixOrderSearch(no
);
}
if (repNode
!= null
) {
return repNode
;
}
System
.out
.println("中序遍历");
if (this.no
== no
) {
return this;
}
if (this.right
!= null
) {
repNode
= this.right
.infixOrderSearch(no
);
}
return repNode
;
}
public HeroNode
postOrderSearch(int no
) {
HeroNode repNode
= null
;
if (this.left
!= null
) {
repNode
= this.left
.postOrderSearch(no
);
}
if (repNode
!= null
) {
return repNode
;
}
if (this.right
!= null
) {
repNode
= this.right
.postOrderSearch(no
);
}
if (repNode
!= null
) {
return repNode
;
}
System
.out
.println("后序遍历");
if (this.no
== no
) {
return this;
}
return repNode
;
}
public HeroNode
mySearch(int no
) {
HeroNode temp
= null
;
if (this.no
< no
&& this.left
!= null
) {
temp
= this.left
.mySearch(no
);
} else if (this.no
> no
&& this.right
!= null
) {
temp
= this.right
.mySearch(no
);
} else {
return this;
}
return temp
;
}
public void delNode(int no
){
if (this.left
!= null
&& left
.no
== no
){
this.left
= null
;
return;
}
if (this.right
!= null
&& right
.no
== no
){
this.right
= null
;
return;
}
if (this.left
!= null
){
this.left
.delNode(no
);
}
if (this.right
!= null
){
this.right
.delNode(no
);
}
}
public void myRemove(int no
){
boolean leftFlag
= this.left
!= null
;
if (leftFlag
&& this.left
.no
== no
){
this.left
= null
;
return;
}
boolean rightFlag
= this.right
!= null
;
if (rightFlag
&& this.right
.no
== no
){
this.right
= null
;
return;
}
if (rightFlag
) {
this.left
.myRemove(no
);
}
if (rightFlag
) {
this.right
.myRemove(no
);
}
}
}
100-101 顺序存储二叉树
100 思路解析
基本说明: 从数据存储来看,数组存储方式和树的存储方式可以相互转换,即数组可以转换成树,树也可以转换成数组,
概念
顺序二叉树只考虑完全二叉树第n个元素的左子节点为 2 * n + 1第n个元素的右子节点为 2 * n + 2第n个元素的父节点为 (n - 1) / 2 表示二叉树中的第几个元素(按0开始编号)
101 顺序存储二叉树代码实现
需求:给你一个数组{1,2,3,4,5,6,7} ,要求以二叉树遍历的方式进行遍历。前序遍历的结果应当为1,2,3,4,5,6,7
package com
.old
.Tree_90
;
public class ArrBinaryTreeDemo {
public static void main(String
[] gsg
) {
int[] arr
= {1, 2, 3, 4, 5, 6, 7,};
ArrBinaryTree arrBinaryTree
= new ArrBinaryTree(arr
);
arrBinaryTree
.preOrder();
System
.out
.println();
arrBinaryTree
.infixOrder();
System
.out
.println();
arrBinaryTree
.postOrder();
}
}
class ArrBinaryTree {
private int[] arr
;
public ArrBinaryTree(int[] arr
) {
this.arr
= arr
;
}
public void preOrder() {
preOrder(0);
}
public void infixOrder() {
infixOrder(0);
}
public void postOrder() {
postOrder(0);
}
public void preOrder(int index
) {
if (arr
== null
|| arr
.length
== 0) {
System
.out
.println("数组为空,不能按照二叉树的遍历");
}
System
.out
.println(arr
[index
]);
int leftIndex
= 2 * index
+ 1;
if (leftIndex
< arr
.length
) {
preOrder(leftIndex
);
}
int rightIndex
= 2 * index
+ 2;
if (rightIndex
< arr
.length
) {
preOrder(rightIndex
);
}
}
public void infixOrder(int index
) {
if (arr
== null
|| arr
.length
== 0) {
System
.out
.println("数组为空,不能按照二叉树的遍历");
}
int leftIndex
= 2 * index
+ 1;
if (leftIndex
< arr
.length
) {
infixOrder(leftIndex
);
}
System
.out
.println(arr
[index
]);
int rightIndex
= 2 * index
+ 2;
if (rightIndex
< arr
.length
) {
infixOrder(rightIndex
);
}
}
public void postOrder(int index
) {
if (arr
== null
|| arr
.length
== 0) {
System
.out
.println("数组为空,不能按照二叉树的遍历");
}
int leftIndex
= 2 * index
+ 1;
if (leftIndex
< arr
.length
) {
postOrder(leftIndex
);
}
int rightIndex
= 2 * index
+ 2;
if (rightIndex
< arr
.length
) {
postOrder(rightIndex
);
}
System
.out
.println(arr
[index
]);
}
}
102-106 线索化二叉树
102-103 线索化二叉树的介绍与思路图解
顺序存储二叉树应用实例 八大排序算法中的堆排序,使用到顺序存储二叉树,
基本介绍
n个节点的二叉链表中含有 n + 1 公式 2n - (n - 1) = n + 1 个空指针域。利用二叉链表中的空指针域,存入指向节点在某种启程遍历次序下的前驱和后继节点的指针(这种附加的的绝佳称为“线索”)这种加上了线索的二叉链表称为线索链表,相应的二叉树称为线索二叉树[Threaded BinaryTree]。根据性质的不同,线索二叉树可分为前序线索二叉树、中序线索二叉树、后序线索二叉树三种一个结点的前一个结点,称为前驱结点一个结点的后一个结点,称为后继节点
104-105 线索二叉树代码实现
package com
.old
.Tree_90
.threadedBinaryTree104_105
;
public class ThreadedBrinaryTreeDemo {
public static void main(String
[] args
) {
HeroNode root
= new HeroNode(1, "tom");
HeroNode node2
= new HeroNode(3, "jack");
HeroNode node3
= new HeroNode(6, "smith");
HeroNode node4
= new HeroNode(8, "mary");
HeroNode node5
= new HeroNode(10, "king");
HeroNode node6
= new HeroNode(14, "dim");
root
.setLeft(node2
);
root
.setRight(node3
);
node2
.setLeft(node4
);
node2
.setRight(node5
);
node3
.setLeft(node6
);
ThreadedBinaryTree threadedBinaryTree
= new ThreadedBinaryTree();
threadedBinaryTree
.setRoot(root
);
threadedBinaryTree
.threadedNodes();
HeroNode leftNode
= node5
.getLeft();
System
.out
.println(leftNode
);
System
.out
.println(rightNode
);
}
}
class ThreadedBinaryTree {
private HeroNode root
;
private HeroNode pre
;
public void setRoot(HeroNode root
) {
this.root
= root
;
}
public void threadedNodes() {
threadedNodes(root
);
}
public void threadedNodes(HeroNode node
) {
if (node
== null
) {
return;
}
threadedNodes(node
.getLeft());
if (node
.getLeft() == null
) {
node
.setLeft(pre
);
node
.setLeftType(Type
.LEFT_PRECURSOR
);
}
if (pre
!= null
&& pre
.getRight() == null
) {
pre
.setRight(node
);
pre
.setRightType(Type
.RIGHT_SUCCESSOR
);
}
pre
= node
;
threadedNodes(node
.getRight());
}
public void preOrder() {
if (this.root
!= null
) {
root
.preOrder();
} else {
System
.out
.println("二叉树为空,无法遍历");
}
}
public void infixOrder() {
if (this.root
!= null
) {
root
.infixOrder();
} else {
System
.out
.println("二叉树为空,无法遍历");
}
}
public void postOrder() {
if (this.root
!= null
) {
root
.postOrder();
} else {
System
.out
.println("二叉树为空,无法遍历");
}
}
public HeroNode
myPreOrderSearch(int no
) {
if (root
== null
) {
return null
;
} else {
return root
.myPreOrderSearch(no
);
}
}
public HeroNode
mySearch(int no
) {
if (root
== null
) {
return null
;
} else {
return root
.mySearch(no
);
}
}
public void myRemove(int no
) {
if (root
== null
) {
return;
}
if (root
.getNo() == no
) {
root
= null
;
return;
}
root
.myRemove(no
);
}
public void delNode(int no
) {
if (root
== null
) {
return;
}
if (root
.getNo() == no
) {
root
= null
;
return;
}
root
.delNode(no
);
}
public HeroNode
preOrderSearch(int no
) {
if (root
== null
) {
return null
;
} else {
return root
.preOrderSearch(no
);
}
}
public HeroNode
infixOrderSearch(int no
) {
if (root
== null
) {
return null
;
} else {
return root
.infixOrderSearch(no
);
}
}
public HeroNode
postOrderSearch(int no
) {
if (root
== null
) {
return null
;
} else {
return root
.postOrderSearch(no
);
}
}
}
class HeroNode {
private int no
;
private String name
;
private HeroNode left
;
private HeroNode right
;
private int leftType
;
private int rightType
;
public HeroNode(int no
, String name
) {
this.no
= no
;
this.name
= name
;
}
@Override
public String
toString() {
return "HeroNode{" +
"no=" + no
+
", name='" + name
+ '\'' +
'}';
}
public void setNo(int no
) {
this.no
= no
;
}
public void setName(String name
) {
this.name
= name
;
}
public void setLeft(HeroNode left
) {
this.left
= left
;
}
public void setRight(HeroNode right
) {
this.right
= right
;
}
public int getNo() {
return no
;
}
public String
getName() {
return name
;
}
public HeroNode
getLeft() {
return left
;
}
public HeroNode
getRight() {
return right
;
}
public int getLeftType() {
return leftType
;
}
public void setLeftType(int leftType
) {
this.leftType
= leftType
;
}
public int getRightType() {
return rightType
;
}
public void setRightType(int rightType
) {
this.rightType
= rightType
;
}
public void preOrder() {
System
.out
.println(this);
if (this.left
!= null
) {
this.left
.preOrder();
}
if (this.right
!= null
) {
this.right
.preOrder();
}
}
public void infixOrder() {
if (this.left
!= null
) {
this.left
.infixOrder();
}
System
.out
.println(this);
if (this.right
!= null
) {
this.right
.infixOrder();
}
}
public void postOrder() {
if (this.left
!= null
) {
this.left
.postOrder();
}
if (this.right
!= null
) {
this.right
.postOrder();
}
System
.out
.println(this);
}
public HeroNode
myPreOrderSearch(int no
) {
System
.out
.println("我的前序遍历");
if (this.no
== no
) {
return this;
}
HeroNode temp
= null
;
if (this.left
!= null
) {
temp
= this.left
.myPreOrderSearch(no
);
}
if (temp
!= null
) {
return temp
;
}
if (this.right
!= null
) {
temp
= this.right
.myPreOrderSearch(no
);
}
return temp
;
}
public HeroNode
preOrderSearch(int no
) {
System
.out
.println("前序遍历");
if (this.no
== no
) {
return this;
}
HeroNode repNode
= null
;
if (this.left
!= null
) {
repNode
= this.left
.preOrderSearch(no
);
}
if (repNode
!= null
) {
return repNode
;
}
if (this.right
!= null
) {
repNode
= this.right
.preOrderSearch(no
);
}
return repNode
;
}
public HeroNode
infixOrderSearch(int no
) {
HeroNode repNode
= null
;
if (this.left
!= null
) {
repNode
= this.left
.infixOrderSearch(no
);
}
if (repNode
!= null
) {
return repNode
;
}
System
.out
.println("中序遍历");
if (this.no
== no
) {
return this;
}
if (this.right
!= null
) {
repNode
= this.right
.infixOrderSearch(no
);
}
return repNode
;
}
public HeroNode
postOrderSearch(int no
) {
HeroNode repNode
= null
;
if (this.left
!= null
) {
repNode
= this.left
.postOrderSearch(no
);
}
if (repNode
!= null
) {
return repNode
;
}
if (this.right
!= null
) {
repNode
= this.right
.postOrderSearch(no
);
}
if (repNode
!= null
) {
return repNode
;
}
System
.out
.println("后序遍历");
if (this.no
== no
) {
return this;
}
return repNode
;
}
public HeroNode
mySearch(int no
) {
HeroNode temp
= null
;
if (this.no
< no
&& this.left
!= null
) {
temp
= this.left
.mySearch(no
);
} else if (this.no
> no
&& this.right
!= null
) {
temp
= this.right
.mySearch(no
);
} else {
return this;
}
return temp
;
}
public void delNode(int no
) {
if (this.left
!= null
&& left
.no
== no
) {
this.left
= null
;
return;
}
if (this.right
!= null
&& right
.no
== no
) {
this.right
= null
;
return;
}
if (this.left
!= null
) {
this.left
.delNode(no
);
}
if (this.right
!= null
) {
this.right
.delNode(no
);
}
}
public void myRemove(int no
) {
boolean leftFlag
= this.left
!= null
;
if (leftFlag
&& this.left
.no
== no
) {
this.left
= null
;
return;
}
boolean rightFlag
= this.right
!= null
;
if (rightFlag
&& this.right
.no
== no
) {
this.right
= null
;
return;
}
if (rightFlag
) {
this.left
.myRemove(no
);
}
if (rightFlag
) {
this.right
.myRemove(no
);
}
}
}
interface Type {
int LEFT_TREE
= 0;
int LEFT_PRECURSOR
= 1;
int RIGHT_TREE
= 0;
int RIGHT_SUCCESSOR
= 1;
}
106 遍历线索化二叉树实现
说明: 对前面的中序线索化二叉树,进行遍历 分析:因为线索化后,各个结点指向有变化,因此原来的遍历方式不能使用,这里需要使用新的方式遍历线索化二叉树,各个节点可以通过线形方式遍历,因此无需递归方式,就提高了遍历的效率。遍历的次序应当和中序遍历保持一致
package com
.old
.Tree_90
.threadedBinaryTree104_106
;
public class ThreadedBrinaryTreeDemo {
public static void main(String
[] args
) {
HeroNode root
= new HeroNode(1, "tom");
HeroNode node2
= new HeroNode(3, "jack");
HeroNode node3
= new HeroNode(6, "smith");
HeroNode node4
= new HeroNode(8, "mary");
HeroNode node5
= new HeroNode(10, "king");
HeroNode node6
= new HeroNode(14, "dim");
root
.setLeft(node2
);
root
.setRight(node3
);
node2
.setLeft(node4
);
node2
.setRight(node5
);
node3
.setLeft(node6
);
ThreadedBinaryTree threadedBinaryTree
= new ThreadedBinaryTree();
threadedBinaryTree
.setRoot(root
);
threadedBinaryTree
.threadedNodes();
HeroNode leftNode
= node5
.getLeft();
HeroNode rightNode
= node5
.getRight();
System
.out
.println(leftNode
);
System
.out
.println(rightNode
);
System
.out
.println("开始遍历");
threadedBinaryTree
.threadList();
}
}
class ThreadedBinaryTree {
private HeroNode root
;
private HeroNode pre
;
public void setRoot(HeroNode root
) {
this.root
= root
;
}
public void threadList() {
HeroNode node
= root
;
while (node
!= null
) {
while (node
.getLeftType() == Type
.LEFT_TREE
){
node
= node
.getLeft();
}
System
.out
.println(node
);
while (node
.getRightType() == Type
.RIGHT_SUCCESSOR
){
node
= node
.getRight();
System
.out
.println(node
);
}
node
= node
.getRight();
}
}
public void threadedNodes() {
threadedNodes(root
);
}
public void threadedNodes(HeroNode node
) {
if (node
== null
) {
return;
}
threadedNodes(node
.getLeft());
if (node
.getLeft() == null
) {
node
.setLeft(pre
);
node
.setLeftType(Type
.LEFT_PRECURSOR
);
}
if (pre
!= null
&& pre
.getRight() == null
) {
pre
.setRight(node
);
pre
.setRightType(Type
.RIGHT_SUCCESSOR
);
}
pre
= node
;
threadedNodes(node
.getRight());
}
public void preOrder() {
if (this.root
!= null
) {
root
.preOrder();
} else {
System
.out
.println("二叉树为空,无法遍历");
}
}
public void infixOrder() {
if (this.root
!= null
) {
root
.infixOrder();
} else {
System
.out
.println("二叉树为空,无法遍历");
}
}
public void postOrder() {
if (this.root
!= null
) {
root
.postOrder();
} else {
System
.out
.println("二叉树为空,无法遍历");
}
}
public HeroNode
myPreOrderSearch(int no
) {
if (root
== null
) {
return null
;
} else {
return root
.myPreOrderSearch(no
);
}
}
public HeroNode
mySearch(int no
) {
if (root
== null
) {
return null
;
} else {
return root
.mySearch(no
);
}
}
public void myRemove(int no
) {
if (root
== null
) {
return;
}
if (root
.getNo() == no
) {
root
= null
;
return;
}
root
.myRemove(no
);
}
public void delNode(int no
) {
if (root
== null
) {
return;
}
if (root
.getNo() == no
) {
root
= null
;
return;
}
root
.delNode(no
);
}
public HeroNode
preOrderSearch(int no
) {
if (root
== null
) {
return null
;
} else {
return root
.preOrderSearch(no
);
}
}
public HeroNode
infixOrderSearch(int no
) {
if (root
== null
) {
return null
;
} else {
return root
.infixOrderSearch(no
);
}
}
public HeroNode
postOrderSearch(int no
) {
if (root
== null
) {
return null
;
} else {
return root
.postOrderSearch(no
);
}
}
}
class HeroNode {
private int no
;
private String name
;
private HeroNode left
;
private HeroNode right
;
private int leftType
;
private int rightType
;
public HeroNode(int no
, String name
) {
this.no
= no
;
this.name
= name
;
}
@Override
public String
toString() {
return "HeroNode{" +
"no=" + no
+
", name='" + name
+ '\'' +
'}';
}
public void setNo(int no
) {
this.no
= no
;
}
public void setName(String name
) {
this.name
= name
;
}
public void setLeft(HeroNode left
) {
this.left
= left
;
}
public void setRight(HeroNode right
) {
this.right
= right
;
}
public int getNo() {
return no
;
}
public String
getName() {
return name
;
}
public HeroNode
getLeft() {
return left
;
}
public HeroNode
getRight() {
return right
;
}
public int getLeftType() {
return leftType
;
}
public void setLeftType(int leftType
) {
this.leftType
= leftType
;
}
public int getRightType() {
return rightType
;
}
public void setRightType(int rightType
) {
this.rightType
= rightType
;
}
public void preOrder() {
System
.out
.println(this);
if (this.left
!= null
) {
this.left
.preOrder();
}
if (this.right
!= null
) {
this.right
.preOrder();
}
}
public void infixOrder() {
if (this.left
!= null
) {
this.left
.infixOrder();
}
System
.out
.println(this);
if (this.right
!= null
) {
this.right
.infixOrder();
}
}
public void postOrder() {
if (this.left
!= null
) {
this.left
.postOrder();
}
if (this.right
!= null
) {
this.right
.postOrder();
}
System
.out
.println(this);
}
public HeroNode
myPreOrderSearch(int no
) {
System
.out
.println("我的前序遍历");
if (this.no
== no
) {
return this;
}
HeroNode temp
= null
;
if (this.left
!= null
) {
temp
= this.left
.myPreOrderSearch(no
);
}
if (temp
!= null
) {
return temp
;
}
if (this.right
!= null
) {
temp
= this.right
.myPreOrderSearch(no
);
}
return temp
;
}
public HeroNode
preOrderSearch(int no
) {
System
.out
.println("前序遍历");
if (this.no
== no
) {
return this;
}
HeroNode repNode
= null
;
if (this.left
!= null
) {
repNode
= this.left
.preOrderSearch(no
);
}
if (repNode
!= null
) {
return repNode
;
}
if (this.right
!= null
) {
repNode
= this.right
.preOrderSearch(no
);
}
return repNode
;
}
public HeroNode
infixOrderSearch(int no
) {
HeroNode repNode
= null
;
if (this.left
!= null
) {
repNode
= this.left
.infixOrderSearch(no
);
}
if (repNode
!= null
) {
return repNode
;
}
System
.out
.println("中序遍历");
if (this.no
== no
) {
return this;
}
if (this.right
!= null
) {
repNode
= this.right
.infixOrderSearch(no
);
}
return repNode
;
}
public HeroNode
postOrderSearch(int no
) {
HeroNode repNode
= null
;
if (this.left
!= null
) {
repNode
= this.left
.postOrderSearch(no
);
}
if (repNode
!= null
) {
return repNode
;
}
if (this.right
!= null
) {
repNode
= this.right
.postOrderSearch(no
);
}
if (repNode
!= null
) {
return repNode
;
}
System
.out
.println("后序遍历");
if (this.no
== no
) {
return this;
}
return repNode
;
}
public HeroNode
mySearch(int no
) {
HeroNode temp
= null
;
if (this.no
< no
&& this.left
!= null
) {
temp
= this.left
.mySearch(no
);
} else if (this.no
> no
&& this.right
!= null
) {
temp
= this.right
.mySearch(no
);
} else {
return this;
}
return temp
;
}
public void delNode(int no
) {
if (this.left
!= null
&& left
.no
== no
) {
this.left
= null
;
return;
}
if (this.right
!= null
&& right
.no
== no
) {
this.right
= null
;
return;
}
if (this.left
!= null
) {
this.left
.delNode(no
);
}
if (this.right
!= null
) {
this.right
.delNode(no
);
}
}
public void myRemove(int no
) {
boolean leftFlag
= this.left
!= null
;
if (leftFlag
&& this.left
.no
== no
) {
this.left
= null
;
return;
}
boolean rightFlag
= this.right
!= null
;
if (rightFlag
&& this.right
.no
== no
) {
this.right
= null
;
return;
}
if (rightFlag
) {
this.left
.myRemove(no
);
}
if (rightFlag
) {
this.right
.myRemove(no
);
}
}
}
interface Type {
int LEFT_TREE
= 0;
int LEFT_PRECURSOR
= 1;
int RIGHT_TREE
= 0;
int RIGHT_SUCCESSOR
= 1;
}