数组存储方式:
若数组添加元素,由于数组大小是固定的,所以每次存储,数组都会扩容创建新的数组,将原来数据拷贝到新的数组,并插入数据。
集合底层是用数组动态扩容。
以9为例,9比7大,放在7的右侧,9比10小,放在10左侧。
10.1.3 二叉树
package tree;
public class BinaryTreeDemo {
public static void main(String[] args){
//创建一棵二叉树
BinaryTree binaryTree = new BinaryTree();
//创建需要的节点
HeroNode root = new HeroNode(1,"sj");
HeroNode node2 = new HeroNode(2,"wy");
HeroNode node3 = new HeroNode(3,"ljy");
HeroNode node4 = new HeroNode(4,"lc");
HeroNode node5 = new HeroNode(5,"gs");
root.setLeft(node2);
root.setRight(node3);
node3.setRight(node4);
node3.setLeft(node5);
//c测试
System.out.println("前序遍历"); //1,2,3,5,4
binaryTree.setRoot(root);
binaryTree.preOrder();
System.out.println("中序遍历"); //2,1,5,3,4
binaryTree.infixOrder();
System.out.println("后序遍历"); //2,5,4,3,1
binaryTree.postOrder();
}
}
//定义二叉树
class BinaryTree{
private HeroNode root; //根节点
public void setRoot(HeroNode root) {
this.root = root;
}
//前序遍历
public void preOrder(){
if (this.root!=null){
this.root.preOrder();
}else {
System.out.println("二叉树为空,无法遍历");
}
}
//中序遍历
public void infixOrder(){
if (this.root!=null){
this.root.infixOrder();
}else {
System.out.println("二叉树为空,无法遍历");
}
}
//后序遍历
public void postOrder(){
if (this.root!=null){
this.root.postOrder();
}else {
System.out.println("二叉树为空,无法遍历");
}
}
}
//先创建HeroNode 节点
class HeroNode{
private int no;
private String name;
private HeroNode left; //默认null
private HeroNode right; //默认null
public HeroNode(int no,String name){
this.name = name;
this.no = no;
}
public int getNo() {
return no;
}
public void setNo(int no) {
this.no = no;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public HeroNode getLeft() {
return left;
}
public void setLeft(HeroNode left) {
this.left = left;
}
public HeroNode getRight() {
return right;
}
public void setRight(HeroNode right) {
this.right = right;
}
@Override
public String toString() {
return "HeroNode{" +
"no=" + no +
", name='" + name + '\'' +
'}';
}
/**
* 前序遍历
*/
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);
}
}
前序遍历:父–>左子树–>右子树
中序遍历:左子树–>父–>右子树
后序遍历:左子树–>右子树–>父
10.1.6 二叉树查找节点
package tree;
public class BinaryTreeDemo {
public static void main(String[] args){
//创建一棵二叉树
BinaryTree binaryTree = new BinaryTree();
//创建需要的节点
HeroNode root = new HeroNode(1,"sj");
HeroNode node2 = new HeroNode(2,"wy");
HeroNode node3 = new HeroNode(3,"ljy");
HeroNode node4 = new HeroNode(4,"lc");
HeroNode node5 = new HeroNode(5,"gs");
root.setLeft(node2);
root.setRight(node3);
node3.setRight(node4);
node3.setLeft(node5);
//c测试
System.out.println("前序遍历"); //1,2,3,5,4
binaryTree.setRoot(root);
binaryTree.preOrder();
System.out.println("中序遍历"); //2,1,5,3,4
binaryTree.infixOrder();
System.out.println("后序遍历"); //2,5,4,3,1
binaryTree.postOrder();
System.out.println("前序遍历查找"); //1,2,3,5,4
HeroNode resNode = binaryTree.preOrderSearch(5);
if (resNode!=null){
System.out.printf("找到,no = %d name = %s",resNode.getNo(),resNode.getName());
}else {
System.out.println("没有找到");
}
System.out.println("中序遍历查找"); //1,2,3,5,4
HeroNode resNode2 = binaryTree.infixOrderSearch(5);
if (resNode2!=null){
System.out.printf("找到,no = %d name = %s",resNode2.getNo(),resNode2.getName());
}else {
System.out.println("没有找到");
}
System.out.println("后序遍历查找"); //1,2,3,5,4
HeroNode resNode3 = binaryTree.infixOrderSearch(5);
if (resNode3!=null){
System.out.printf("找到,no = %d name = %s",resNode3.getNo(),resNode3.getName());
}else {
System.out.println("没有找到");
}
}
}
//定义二叉树
class BinaryTree{
private HeroNode root; //根节点
public void setRoot(HeroNode root) {
this.root = root;
}
//前序遍历
public void preOrder(){
if (this.root!=null){
this.root.preOrder();
}else {
System.out.println("二叉树为空,无法遍历");
}
}
//中序遍历
public void infixOrder(){
if (this.root!=null){
this.root.infixOrder();
}else {
System.out.println("二叉树为空,无法遍历");
}
}
//后序遍历
public void postOrder(){
if (this.root!=null){
this.root.postOrder();
}else {
System.out.println("二叉树为空,无法遍历");
}
}
//前序遍历查找
public HeroNode preOrderSearch(int no){
if (root!=null){
return root.postOrderSearch(no);
}else {
return null;
}
}
//中序遍历查找
public HeroNode infixOrderSearch(int no){
if (root!=null){
return root.infixOrderSearch(no);
}else {
return null;
}
}
//后续遍历查找
public HeroNode postOrderSearch(int no){
if (root!=null){
return root.postOrderSearch(no);
}else {
return null;
}
}
}
//先创建HeroNode 节点
class HeroNode{
private int no;
private String name;
private HeroNode left; //默认null
private HeroNode right; //默认null
public HeroNode(int no,String name){
this.name = name;
this.no = no;
}
public int getNo() {
return no;
}
public void setNo(int no) {
this.no = no;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public HeroNode getLeft() {
return left;
}
public void setLeft(HeroNode left) {
this.left = left;
}
public HeroNode getRight() {
return right;
}
public void setRight(HeroNode right) {
this.right = right;
}
@Override
public String toString() {
return "HeroNode{" +
"no=" + no +
", name='" + name + '\'' +
'}';
}
/**
* 前序遍历
*/
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 preOrderSearch(int no){
//比较当前节点是不是
if (this.no == no){
return this;
}
HeroNode resNode = null;
if (this.left!=null){
resNode = this.left.preOrderSearch(no);
}
if (resNode!=null){
//左子树找到
return resNode;
}
if (this.right!=null){
resNode = this.right.preOrderSearch(no);
}
return resNode;
}
//中序遍历查找
public HeroNode infixOrderSearch(int no){
HeroNode resNode = null;
if (this.left!=null){
resNode = this.left.infixOrderSearch(no);
}
if (resNode!=null){
return resNode;
}
if (this.no == no){
return this;
}
if (this.right!=null){
resNode = this.right.infixOrderSearch(no);
}
return resNode;
}
//后续遍历查找
public HeroNode postOrderSearch(int no){
HeroNode resNode = null;
if (this.left!=null){
resNode = this.left.postOrderSearch(no);
}
if (resNode!=null){
return resNode;
}
if (this.right!=null){
resNode = this.right.postOrderSearch(no);
}
if (resNode!=null){
return resNode;
}
if (this.no == no){
return this;
}
return resNode;
}
}
二叉树删除节点
package tree;
public class BinaryTreeDemo {
public static void main(String[] args){
//创建一棵二叉树
BinaryTree binaryTree = new BinaryTree();
//创建需要的节点
HeroNode root = new HeroNode(1,"sj");
HeroNode node2 = new HeroNode(2,"wy");
HeroNode node3 = new HeroNode(3,"ljy");
HeroNode node4 = new HeroNode(4,"lc");
HeroNode node5 = new HeroNode(5,"gs");
root.setLeft(node2);
root.setRight(node3);
node3.setRight(node4);
node3.setLeft(node5);
binaryTree.setRoot(root);
//测试删除节点
System.out.println("删除前,前序遍历");
binaryTree.preOrder();
binaryTree.delNode(3);
System.out.println("删除后,前序遍历");
binaryTree.preOrder();
}
}
//定义二叉树
class BinaryTree{
private HeroNode root; //根节点
public void setRoot(HeroNode root) {
this.root = root;
}
//删除节点
public void delNode(int no){
if (root!=null){
//如果只有一个root节点,判断root是不是要删除的节点
if (root.getNo()==no){
root = null;
}else {
//递归删除
root.delNode(no);
}
}else {
System.out.println("空树不能删除");
}
}
//前序遍历
public void preOrder(){
if (this.root!=null){
this.root.preOrder();
}else {
System.out.println("二叉树为空,无法遍历");
}
}
//中序遍历
public void infixOrder(){
if (this.root!=null){
this.root.infixOrder();
}else {
System.out.println("二叉树为空,无法遍历");
}
}
//后序遍历
public void postOrder(){
if (this.root!=null){
this.root.postOrder();
}else {
System.out.println("二叉树为空,无法遍历");
}
}
//前序遍历查找
public HeroNode preOrderSearch(int no){
if (root!=null){
return root.postOrderSearch(no);
}else {
return null;
}
}
//中序遍历查找
public HeroNode infixOrderSearch(int no){
if (root!=null){
return root.infixOrderSearch(no);
}else {
return null;
}
}
//后续遍历查找
public HeroNode postOrderSearch(int no){
if (root!=null){
return root.postOrderSearch(no);
}else {
return null;
}
}
}
//先创建HeroNode 节点
class HeroNode{
private int no;
private String name;
private HeroNode left; //默认null
private HeroNode right; //默认null
public HeroNode(int no,String name){
this.name = name;
this.no = no;
}
public int getNo() {
return no;
}
public void setNo(int no) {
this.no = no;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public HeroNode getLeft() {
return left;
}
public void setLeft(HeroNode left) {
this.left = left;
}
public HeroNode getRight() {
return right;
}
public void setRight(HeroNode right) {
this.right = right;
}
@Override
public String toString() {
return "HeroNode{" +
"no=" + no +
", name='" + name + '\'' +
'}';
}
/**
* 递归删除节点
* 如果删除的是叶子节点,则删除该节点
* 如果删除的是非叶子节点,删除该子树
* @param no
*/
public void delNode(int no){
//判断左子节点
if (this.left!=null && this.left.no==no){
this.left = null;
return;
}
//判断右子节点
if (this.right!=null && this.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 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 preOrderSearch(int no){
//比较当前节点是不是
if (this.no == no){
return this;
}
HeroNode resNode = null;
if (this.left!=null){
resNode = this.left.preOrderSearch(no);
}
if (resNode!=null){
//左子树找到
return resNode;
}
if (this.right!=null){
resNode = this.right.preOrderSearch(no);
}
return resNode;
}
//中序遍历查找
public HeroNode infixOrderSearch(int no){
HeroNode resNode = null;
if (this.left!=null){
resNode = this.left.infixOrderSearch(no);
}
if (resNode!=null){
return resNode;
}
if (this.no == no){
return this;
}
if (this.right!=null){
resNode = this.right.infixOrderSearch(no);
}
return resNode;
}
//后续遍历查找
public HeroNode postOrderSearch(int no){
HeroNode resNode = null;
if (this.left!=null){
resNode = this.left.postOrderSearch(no);
}
if (resNode!=null){
return resNode;
}
if (this.right!=null){
resNode = this.right.postOrderSearch(no);
}
if (resNode!=null){
return resNode;
}
if (this.no == no){
return this;
}
return resNode;
}
}
10.2 顺序存储二叉树
package tree.ArrBinaryTree;
public class ArrBinaryTreeDemo {
public static void main(String[] args){
int[] arr = {
1,2,3,4,5,6,7};
//创建tree
ArrBinaryTree arrBinaryTree = new ArrBinaryTree(arr);
System.out.println("前序");
arrBinaryTree.preOrder(); // 1245367
System.out.println("中序");
arrBinaryTree.midOrder();
System.out.println("后序");
arrBinaryTree.laOrder();
}
}
package tree.ArrBinaryTree;
//实现顺序存储二叉树遍历
public class ArrBinaryTree {
private int[] arr; //存储数据节点的数组
public ArrBinaryTree(int[] arr){
this.arr = arr;
}
//重载
public void preOrder(){
this.preOrder(0);
}
public void midOrder(){
this.midOrder(0);
}
public void laOrder(){
this.laOrder(0);
}
/**
* //编写方法,完成顺序存储二叉树的前序遍历
* @param index 数组下标
*/
public void preOrder(int index){
//如果数组为空,或者arr.length = 0
if (arr==null || arr.length==0){
System.out.println("数组为空,无法遍历");
}
//输出当前元素
System.out.println(arr[index]);
//向左递归遍历
if ((index*2)+1<arr.length){
preOrder(2*index+1);
}
//向右递归
if ((index*2)+2 < arr.length){
preOrder(2*index+2);
}
}
/**
* 中序遍历
* @param index
*/
public void midOrder(int index){
if (arr==null || arr.length==0){
System.out.println("数组为空,无法遍历");
}
//左递归遍历
if ((index*2)+1<arr.length){
midOrder(2*index+1);
}
//输出当前元素
System.out.println(arr[index]);
//右递归
if ((index*2)+2<arr.length){
midOrder(2*index+2);
}
}
/**
* 后序遍历
* @param index
*/
public void laOrder(int index){
if (arr==null||arr.length==0){
System.out.println("数组为空,无法遍历");
}
//左递归
if ((index*2)+1 < arr.length){
laOrder(2*index+1);
}
//右递归
if ((index*2+2) < arr.length){
laOrder(2*index+2);
}
//输出
System.out.println(arr[index]);
}
}
10.3 线索化二叉树
package tree.ThreadedTree;
public class ThreadBinaryTreeDemo {
public static void main(String[] args){
//测试
HeroNode root = new HeroNode(1, "a");
HeroNode node2 = new HeroNode(3, "c");
HeroNode node3 = new HeroNode(6, "a6");
HeroNode node4 = new HeroNode(8, "a8");
HeroNode node5 = new HeroNode(10, "a10");
HeroNode node6 = new HeroNode(14, "a14");
//二叉树,创建
root.setLeft(node2);
root.setRight(node3);
node2.setLeft(node4);
node2.setRight(node5);
node3.setLeft(node6);
//线索化
ThreadedBinaryTree threadedBinaryTree = new ThreadedBinaryTree();
threadedBinaryTree.setRoot(root);
threadedBinaryTree.threadedNodes();
//测试:10号节点
HeroNode leftNode = node5.getLeft();
System.out.println("10号节点的前驱节点是:" + leftNode); //3 c
HeroNode rightNode = node5.getRight();
System.out.println("10号节点的后继节点是:" + rightNode);//1 a
}
}
package tree.ThreadedTree;
public class ThreadedBinaryTree {
private HeroNode root;
//为实现线索化,需要创建要给指向当前节点的前驱节点的指针
//在递归进行线索化时,pre总是保留前一个节点
private HeroNode pre = null;
public void setRoot(HeroNode root) {
this.root = root;
}
//重载线索化
public void threadedNodes(){
this.threadedNodes(root);
}
/**
* 二叉树中序线索化方法
* @param node 当前需要线索化的方法
*/
public void threadedNodes(HeroNode node){
if (node == null){
return;
}
// 1. 先线索化左子树
threadedNodes(node.getLeft());
// 2. 线索化当前节点
//处理当前节点的前驱节点
if (node.getLeft() == null){
//让当前节点的左指针指向前驱节点
node.setLeft(pre);
//修改当前节点的做针织类型,指向前驱节点
node.setLeftType(1);
}
//处理后继节点
if (pre!=null &&pre.getRight()==null){
//让前驱节点的右指针指向当前节点
pre.setRight(node);
//修改前驱节点的右指针类型
pre.setRightType(1);
}
//每处理一个节点后,让当前节点是下一个节点的前驱节点
pre = node;
// 3. 线索化右子树
threadedNodes(node.getRight());
}
}
package tree.ThreadedTree;
public class HeroNode {
private int no;
private String name;
private HeroNode left;
private HeroNode right;
// 0 左子树 1 前驱节点
private int leftType;
// 0 右子树 1 后继节点
private int rightType;
public HeroNode(int no,String name){
this.no = no;
this.name = name;
}
public int getNo() {
return no;
}
public void setNo(int no) {
this.no = no;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public HeroNode getLeft() {
return left;
}
public void setLeft(HeroNode left) {
this.left = left;
}
public HeroNode getRight() {
return right;
}
public void setRight(HeroNode right) {
this.right = 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;
}
@Override
public String toString() {
return "HeroNode{" +
"no=" + no +
", name='" + name + '\'' +
'}';
}
}