二叉树
- 每个节点上最多有两个子节点
- 满二叉树
- 完全二叉树
- 最后一层所有子节点左边连续
- 倒数第二层叶子节点右边连续
遍历
- 遍历
- 前序
- 先输出当前节点
- 如果左子节点不为空,则递归前序遍历
- 如果右子节点不为空,则递归前序遍历
- 中序
- 如果当前节点左子节点不为空,则递归中序遍历
- 输出当前节点
- 如果当前节点右子节点不为空,则递归中序遍历
- 后序
- 如果当前节点左子节点不为空,则递归中序遍历
- 如果当前节点右子节点不为空,则递归中序遍历
- 输出当前节点
public class Demo{
public static void main(String[] args){
// 创建二叉树
BinaryTree binaryTree = new BinaryTree();
HeroNode node1 = new HeroNode(1."xx");
HeroNode node2 = new HeroNode(2."xx");
HeroNode node3 = new HeroNode(3."xx");
HeroNode node4 = new HeroNode(4."xx");
HeroNode node5 = new HeroNode(5."xx");
root1.setLeft(node2);
root1.setRight(node3);
node3.setRight(node4);
node3.setLeft(node5);
// 前序
binaryTree.preOrder();
// 中序
binaryTree.infixOrder();
// 后续
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("二叉树为空");
}
}
}
class HeroNode{
private int no;
private String name;
private HeroNode left;
private HeroNode right;
public HeroNode(int no,String name){
super();
this.no = no;
this.name = name;
}
// get set
// toString no 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.preOrder();
}
// 先输出父节点
System.out.println(this);
if(this.right!=null){
this.right.preOrder();
}
}
// 后续遍历
public void postOrder(){
if(this.left!=null){
this.left.preOrder();
}
if(this.right!=null){
this.right.preOrder();
}
// 先输出父节点
System.out.println(this);
}
}
查找
class HeroNode{
private int no;
private String name;
private HeroNode left;
private HeroNode right;
public HeroNode(int no,String name){
super();
this.no = no;
this.name = name;
}
// get set
// toString no name
// 前序查找
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(){
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(){
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;
}
}
删除
- 删除
- 如果删除的节点是叶子节点,删除该节点
- 如果删除的节点非叶子节点,删除该子树
- 判断子节点是否需要删除
- 如果左子节点需要删除,则this.left = null
- 如果右子节点需要删除,则this.right = null
- 如果没有删除,向左递归
- 如果没有删除,向右递归
class HeroNode{
private int no;
private String name;
private HeroNode left;
private HeroNode right;
public HeroNode(int no,String name){
super();
this.no = no;
this.name = name;
}
// get set
// toString no name
// 删除
public void delNode(int no){
if(this.left!=null &7 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);
}
}
}
// BinaryTree
public void delNode(int no){
if(root!=null){
if(root.getNo()==no){
root = null;
}else{
root.delNode(no);
}
}else{
System.out.println("空树,不能为空");
}
}
顺序存储二叉树
- 顺序存储二叉树
- 完全二叉树
- 第n个元素的左子节点2n+1
- 第n个元素的右子节点2n+2
- 第n个元素的父节点(n-1)/2
public class Demo{
public sttaic void main(String[] args){
int[] arr = {1,2,3,4,5,6,7};
ArrBinaryTree arrBinary = new ArrBinaryTree(arr);
arrBinary.preOrder(0);// 124367
}
}
class ArrBinaryTree{
private int[] arr;
public ArrBinaryTree(int[] arr){
this.arr = arr;
}
// 编写一个方法,完成顺序二叉树的前序遍历
public void preOrder(int index){
// 如果数组为空 或者arr.length = 0
if(arr==null|| arr.length==0){
System.out.println("数组为空,不能前序遍历");
}
// 输出当前元素
Systm.out.println(arr[index]);
// 向左递归遍历
if((index*2+1)
preOrder(2*index + 1);
}
// 向右遍历递归
if((index*2+2)
preOrder(2*ubdex+2);
}
}
}
线索二叉树
- n个二叉链表有n+1个空指针域
- 前序线索二叉树
- 中序线索二叉树
- 后序线索二叉树
public class Demo{
public static void main(String[] args){
}
}
class BinaryTree{
private HeroNOde root;
// 指向当前节点的前驱节点的指针
private HeroNode pre = null;
// setRoot
public void threadedNotes(HeroNode node){
// 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())
}
}
calss HeroNode{
private int no;
private String name;
private HeroNode left;
private HeroNode right;
// 0 左子树 1 前驱节点
private int leftType;
// 0 右子树 1 后继节点
private int rigthType;
}
线索化二叉树遍历
// 遍历线索化二叉树
public void threadedList(){
// 定义一个遍历 存储当前遍历的系欸但 从root开始
HeroNode node = root;
while(node!=null){
// 循环找到leftType==1的系欸但
// 后面随着遍历而发生变化
while(node.getLeftType()==0){
node = node.getLeftType();
}
// 打印当前节点
System.out.println(node);
// 如果当前系欸但右指针指向是后继节点,就一直输出
while(node.getRightType()==1){
// 获取当前系欸但的后继节点
node = node.getRight();
System.out.println(node);
}
// 替换这个遍历节点
node = node.getRight();
}
}
堆排序
- 堆排序
- 旋转排序
- 完全二叉树
- 大顶堆
- 每个节点大于等于左右节点的值
- arr[i]>=arr[2i+1]&&arr[i]>=arr[2i+2]
- 小顶堆
- 每个节点但小于等于左右节点的值
- arr[i]<=arr[2i+1]&&arr[i]<=arr[2i+2]
public class HeapSort{
public static void main(String[] args){
int[] arr = {4,6,8,5,9};
}
public static void heapSort(int arr[]){
System.out.println("堆排序");
// 将无序数组构成一个堆(大顶堆)
for(int i=arr.length/2-1;i>=0;i--){
adjustHeap(arr,i,arr.length);
}
// 将堆顶元素与尾元素交换(最大元素下沉到末尾)
// 重新调整结构,再次满足堆定义
for(int j=arr.length-1;j>0;j--){
// 交换
temp = arr[j];
arr[j] = arr[0];
arr[0] = temp;
adjustHeap(arr,0,j)
}
}
// 将数组调整为大顶堆
// arr 待调整的数组
// i 非叶子节点数组索引
// length 对多少个元素进行调整,逐渐减少
public void static adjustHeap(int arr[],int i,int length){
// 先取出当前元素的值,保存在零时变量
int temp = arr[i];
// k=i*2+1 k是i的左子节点
for(int k=i*2+1;k
if(k+1// 左子节点小于右子节点
k++;
}
if(arr[k]>temp){// 子节点大于父节点
arr[i] = arr[k]; // 较大值赋给当前节点
i = k; // i指向k,继续循环
}else{
break;
}
}
// 循环结束,已经将i为父节点的树最大值,放在了局部最顶
arr[i] = temp; // 将temp值放到调整后的位置
}
}