JAVA基础算法与数据结构

Java基础算法

常见排序算法

内部排序(重点)

插入排序

直接插入排序(有序表和无序表的排序)

package com.kuang.pojo;

import java.util.Arrays;

public class insertSort {
   public static void main(String[] args) {
       int[] arr ={103,-1,94,73};
       insertSort(arr);
  }
   public static void insertSort(int[] arr) {
       for (int i = 1; i < arr.length; i++) {
           int insertVal=arr[i];
           int insertIndex=i-1;
           while (insertIndex >= 0 && insertVal < arr[insertIndex]) {
               arr[insertIndex+1]=arr[insertIndex];//insertIndex后移 找插入位置
               insertIndex--;
          }
           arr[insertIndex+1]=insertVal;//插入位置找到 两数交换
           System.out.println(Arrays.toString(arr));
      }

  }
}

速度测试:大概5秒

希尔排序(分组交换法或移位法)

重点移位法:

package com.kuang.pojo;

import java.util.Arrays;

public class ShellSort {
   public static void main(String[] args) {
       int[] arr={8,9,4,6,3,0,2,7,5};
       System.out.println("排序前");
       System.out.println(Arrays.toString(arr));
       ShellSort(arr);
       System.out.println("排序后");
       System.out.println(Arrays.toString(arr));
  }

   public static void ShellSort(int[] arr) {
       for (int gap = arr.length / 2; gap > 0; gap /= 2) {
           //从gap开始 逐个对其所在的组进行插入排序
           for (int i = gap; i < arr.length; i++) {
               int j=i;
               int temp=arr[j];
               if (arr[j] < arr[j - gap]) {
                   while (j - gap >= 0 && temp < arr[j - gap]) {
                       //移动
                       arr[j]=arr[j-gap];
                       j=j-gap;
                  }
                   //退出while后 给temp插入位置
                   arr[j]=temp;
              }
          }
      }
  }
}

速度测试:大概1秒

选择排序

简单选择排序(从变动的数组中选择最小或最大的数和数组前面的数作比较 再交换)

package com.kuang.pojo;
import java.util.Arrays;

public class xz {
   public static void main(String[] args) {
       int[] arr = {344, 193, 1, 48};
       System.out.println("排序前");
       System.out.println(Arrays.toString(arr));
       xz(arr);
       System.out.println("排序后");
       System.out.println(Arrays.toString(arr));
  }
   private static void xz(int[] arr) {
       for (int i = 0; i < arr.length - 1; i++) {
           int minIndex=i;
           int min=arr[i];
           for (int j = i + 1; j < arr.length; j++) {
               if (min > arr[j]) {
                   min=arr[j];//重置min
                   minIndex=j;//重置miniIndex
              }
          }
//将最小值放在arr[i] 即交换
           if (minIndex != i) {
               arr[minIndex]=arr[i];
               arr[i]=min;
          }
      }
  }
}

速度测试:大概2秒

交换排序

冒泡排序(相邻数之间比大小排序 随着索引的移动 排序次数逐渐减少 直到排序完成)

package com.kuang.pojo;

import java.util.Arrays;

public class mp {
   public static void main(String[] args) {
       int arr[] ={3,9,-1,10,-2};
       int temp=0;
       boolean flag=false;//标识量 表示是否进行过交换
       for (int i = 0; i < arr.length-1; i++) {
           for (int j = 0; j < arr.length - 1 - i; j++) {
               if (arr[j]>arr[j+1]) {
                   flag=true;
                   temp=arr[j];
                   arr[j]=arr[j+1];
                   arr[j+1]=temp;
              }
          }
           System.out.print(Arrays.toString(arr));
           if (!flag) {//一趟中一次没有交换过
               break;
          }else{
               flag=false;//重置
          }
      }

  }
}

速度测试:大概14秒

快速排序(取中间值 按左小右大的方式排列 依次按递归方式排序)

package com.kuang.pojo;

import java.util.Arrays;

public class QuickSort {
   public static void main(String[] args) {
       int[] arr={-4,48,0,-6,394,9};
       QuickSort(arr,0,arr.length-1);
       System.out.println("arr="+ Arrays.toString(arr));
  }
   public static void QuickSort(int[] arr,int left,int right) {
       int l=left;
       int r=right;
       int pivot=arr[(left+right)/2];
       int temp=0;//中间值
       //while循环的目的是 把比pivot小的数放在左面 比pivot大的数放在右面
       while (l < r) {
           //从左面一直找 直到找到大于等于pivot的值
           while (arr[l] < pivot) {
               l+=1;
          }
           //从最右面一直找 直到找到小于等于pivot的值
           while (arr[r] > pivot) {
               r-=1;
          }
           if (l >= r) {
               break;
          }
           //交换
           temp=arr[l];
           arr[l]=arr[r];
           arr[r]=temp;
           //如果交换完 发现arr[l]==pivot 相等r-- 前移
           if (arr[l] == pivot) {
               r-=1;
          }
           //如果交换完 发现arr[r]==pivot 相等l++ 后移
           if (arr[r] == pivot) {
               l+=1;
          }
      }
       //若l=r 必须 l++ r-- 防止死循环
       if (l == r) {
           l+=1;
           r-=1;
      }
       //向左递归
       if (left < r) {
           QuickSort(arr,left,r);
      }
       //向右递归
       if (right > l) {
           QuickSort(arr,l,right);
      }
  }
}

速度测试:大概2秒

堆排序

代码参考图: 最后为 4 5 6 8 9

image-20211005221542901

import java.util.Arrays;

public class HeapSort {
   public static void main(String[] args) {
       int arr[] = {4, 6, 8, 5, 9};
       heapSort(arr);
  }

   public static void heapSort(int arr[]) {
       int temp = 0;
       System.out.println("堆排序");

       //分部完成
//       adjustHeap(arr,1,arr.length);
//       System.out.println("第一次"+ Arrays.toString(arr));
//       adjustHeap(arr,0,arr.length);
//       System.out.println("第二次"+ Arrays.toString(arr));//9 6 8 5 4
       
       //最终代码
       //将无序数列构建成一个堆 根据升序降序需求选择大项堆或小项堆
       //将堆项元素和末尾元素交换 反复调整 交换步骤 直到有序
       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);
      }
       System.out.println("数组=" + Arrays.toString(arr));//4 5 6 8 9
  }

   //将一个数组调整成一个大顶堆   int arr[]={4,6,8,5,9};==>adjustHeap==>得到{4,9,8,5,6}
   //若再次调用 得到{9,6,8,5,4}
   // arr 待调整数组 i 表示非叶子节点在数组中的索引
   // lenght 表示对多少个元素调整
   public static void adjustHeap(int arr[], int i, int lenght) {
       int temp = arr[i];//取出当前元素值
       //开始调整 k:以i为代表的非叶子节点的左子节点
       for (int k = i * 2 + 1; k < lenght; k = k * 2 + 1) {
           if (k + 1 < lenght && arr[k] < arr[k + 1]) {
               //说明左子节点的值小于右子节点的值
               k++;
          }
           if (arr[k] > temp) {
               //如果子节点大于父节点
               arr[i] = arr[k];//把大的值赋给当前节点 然后循环
               i = k;
          } else {
               break;
          }
      }
//循环结束后 已经将以i为父节点的数的最大值 放在了最顶部
       arr[i] = temp;
  }
}

速度测试:大概5秒

归并排序

import java.util.Arrays;

public class MergetSort {
   public static void main(String[] args) {
       int[] arr={3,8,7,4,6,9,2,1};
       //归并需要一个额外空间
       int temp[]=new int[arr.length];
       mergeSort(arr,0,arr.length-1,temp);
       System.out.println("排序后="+ Arrays.toString(arr));
  }
   //分加和的方法
   public static void mergeSort(int[] arr,int left,int right,int[] temp) {
       if (left < right) {
           int mid=(left+right)/2;
           //向左递归进行分解
           mergeSort(arr,left,mid,temp);
           //向右递归进行分解
           mergeSort(arr,mid+1,right,temp);
           //合并
           merge(arr,left,mid,right,temp);
      }
  }

   //合并的方法
   public static void merge(int[] arr,int left,int mid,int right,int[] temp) {
       int i=left;//初始化i 左边有序列的初始索引
       int j=mid+1;//初始化j 右边有序列的初始索引
       int t=0;
       //一 先把左右两边数据按照规则填充到temp数组
       while (i <= mid && j <= right) {
           if (arr[i] <= arr[j]) {
               temp[t] = arr[i];
               t += 1;
               i += 1;
          } else {//反之 将右边数据填充到temp数组中
               temp[t]=arr[j];
               t+=1;
               j+=1;
          }
      }
       //二 把剩余一边的数据依次填充到temp中
       while (i <= mid) {//若左边有剩余 则全部填充到temp
           temp[t]=arr[i];
           t += 1;
           i += 1;
      }
       while (j<= right) {//若右边有剩余 则全部填充到temp
           temp[t]=arr[j];
           t += 1;
           j += 1;
      }
       //三 将temp数组拷贝到arr
       t=0;
       int tempLeft=left;
       while (tempLeft <= right) {
           arr[tempLeft]=temp[t];
           t+=1;
           tempLeft+=1;
      }
  }
}

速度测试:大概3秒

基数排序

(桶排序 分别按照个位 十位 百位... 把数按顺序放在相应的桶下标 再按顺序组合 进行几轮后出结果)

import java.util.Arrays;

public class RadixSort {
   public static void main(String[] args) {
       int arr[] = {48, 9, 589, 307, 23, 135};
       radixSort(arr);
  }

   public static void radixSort(int[] arr) {
       //得到数组最大的位数
       int max=arr[0];
       for (int i = 1; i < arr.length; i++) {
           if (arr[i] > max) {
               max=arr[i];
          }
      }
       //得到最大位数是几位数
       int maxLength=(max+"").length();
       int[][] bucket = new int[10][arr.length];
       int[] bucketCounts = new int[10];
       //循环代码处理
       for (int i = 0, n=1; i < maxLength; i++,n*=10) {
           for (int j = 0; j < arr.length; j++) {
               int digitElement = arr[j] /n % 10;
               //放到对应桶中
               bucket[digitElement][bucketCounts[digitElement]] = arr[j];
               bucketCounts[digitElement]++;
          }
           //依次取出数据 放入原来数组
           int index = 0;
           //遍历
           for (int k = 0; k < bucketCounts.length; k++) {
               //若桶中有数据 我们才放入原数组
               if (bucketCounts[k] != 0) {
                   //循环
                   for (int l = 0; l < bucketCounts[k]; l++) {
                       arr[index++] = bucket[k][l];
                  }
              }
               bucketCounts[k] = 0;
          }
           System.out.println("arr="+ Arrays.toString(arr));
      }
  }
}

速度测试:不到1秒 非常快

查找算法

二分查找

前提 该数组必须有序

import java.util.ArrayList;
import java.util.List;

public class BinarySearch {
   
   public static void main(String[] args) {
       int arr[] = {1, 8, 10, 38, 49, 840, 2000,10,10};
       //int resIndex = binarySearch(arr, 0, arr.length - 1, 10);
       //System.out.println("resIndex=" + resIndex);
       List<Integer> resIndexlist=binarySearch2(arr,0,arr.length-1,10);
       System.out.println("resIndexlist=" + resIndexlist);
  }

   /*
       arr 数组
       left 左边的索引
       right 右边的索引
       findVal 要查找的值

   */
   public static int binarySearch(int[] arr, int left, int right, int findVal) {
       //为防止出现死递归
       if (left > right) {
           return -1;
      }
       int mid = (left + right) / 2;
       int midVal = arr[mid];
       if (findVal > midVal) {
           //向右递归
           return binarySearch(arr, mid + 1, right, findVal);
      } else if (findVal < midVal) {//向左递归
           return binarySearch(arr, left, mid - 1, findVal);
      } else {
           return mid;

      }
  }

   public static ArrayList<Integer> binarySearch2(int[] arr, int left, int right, int findVal) {
       //为防止出现死递归
       if (left > right) {
           return new ArrayList<Integer>();
      }
       int mid = (left + right) / 2;
       int midVal = arr[mid];
       if (findVal > midVal) {
           //向右递归
           return binarySearch2(arr, mid + 1, right, findVal);
      } else if (findVal < midVal) {//向左递归
           return binarySearch2(arr, left, mid - 1, findVal);
      } else {
           ArrayList<Integer> resIndexlist = new ArrayList<Integer>();
           //向左边扫描 将所有满足条件的下标 都加入到集合中
           int temp = mid - 1;
           while (true) {
               if (temp < 0 || arr[temp] != findVal) {
                   break;
              }
               //否则就放入集合中
               resIndexlist.add(temp);
               temp -= 1;//左移
          }
           resIndexlist.add(mid);
           //右移
           temp =mid+1;
           while (true) {
               if (temp > arr.length - 1 || arr[temp] != findVal) {
                   break;
              }
               //否则就放入集合中
               resIndexlist.add(temp);
               temp += 1;//左移

          }
           return resIndexlist;

      }
  }

}

插值查找(类似于二分查找 适应于多数据)

代码公式:

int mid=low+(high-low)*(key-arr[low])/(arr[high]-arr[low]);

数据结构

哈希表结构(散列表)

根据关键码值来进行访问的数据结构

import java.util.Scanner;

public class HashTabDemo {
   public static void main(String[] args) {
       //创建hash表
       HashTab hashTab=new HashTab(7);
       //菜单
         String key="";
         Scanner scanner=new Scanner(System.in);
       while (true) {
           System.out.println("add: 添加雇员");
           System.out.println("list: 显示雇员");
           System.out.println("find: 查找雇员");
           System.out.println("exit: 退出系统");
           key=scanner.next();
           switch (key) {
               case "add":
                   System.out.println("输入id");
                   int id = scanner.nextInt();
                   System.out.println("输入名字");
                   String name=scanner.next();
                   //创建雇员
                   Emp emp = new Emp(id, name);
                   hashTab.add(emp);
                   break;
               case "list":
                   hashTab.list();
                   break;
               case "find":
                   System.out.println("请输入要查找的id");
                   id=scanner.nextInt();
                   hashTab.findEmpById(id);
                   break;
               case "exit":
                   scanner.close();
                   System.exit(0);
               default:
                   break;

          }
      }

  }
}

//创建hashTab
class HashTab {
   private  int size;//表示有多少条链表
   private EmpLinkedList[] empLinkedListArray;
   //构造器
   public HashTab(int size) {
       this.size=size;
       //初始化empLinkedListArray
       empLinkedListArray=new EmpLinkedList[size];
       //不要忘记分别初始化每条链表
       for (int i = 0; i < size; i++) {
           empLinkedListArray[i]=new EmpLinkedList();
      }
  }
   //添加雇员
   public void add(Emp emp) {
       //根据员工id 得到该员工应该添加到哪条链表
       int empLinkedListNO=hashFun(emp.id);
       //添加链表
       empLinkedListArray[empLinkedListNO].add(emp);

  }
   //遍历所有链表
   public void list() {
       for (int i = 0; i < size; i++) {
           empLinkedListArray[i].list(i);
      }
  }
   //查找雇员
   public void findEmpById(int id) {
       int empLinkedListNO=hashFun(id);

       Emp emp = empLinkedListArray[empLinkedListNO].findEmoById(id);
       if (emp != null) {
           System.out.printf("在第%d条链表找到该雇员 id=%d\n",(empLinkedListNO+1),id);
      } else {
           System.out.println("在哈希表中 没有找到该雇员");
      }
  }
   //编写散列函数
   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) {
           super();
           this.id = id;
           this.name = name;

      }
  }
//链表
   class EmpLinkedList {
       private Emp head;
       public void add(Emp emp) {
           //如果添加第一个雇员
           if (head == null) {
               head=emp;
               return;
          }
           //若不是 则使用辅助定位指针 定位
           Emp curEmp=head;
           while (true) {
               if (curEmp.next==null) {
                   break;
              }
              curEmp=curEmp.next;//后移
          }
           //退出时 直接将emp加到链表最后即可
           curEmp.next=emp;
      }
       //遍历链表
       public void list(int no) {
           if (head == null) {
               System.out.println("第"+no+"链表为空");
               return;
          }
           System.out.print("第"+no+"链表为");
           Emp curEmp=head;//辅助指针
           while (true) {
               System.out.printf("=》id=%d name=%s\t", curEmp.id, curEmp.name);
               if (curEmp.next == null) {//已经为最后节点
                   break;
              }
               curEmp=curEmp.next;
          }
           System.out.println();
      }
       //根据id查找雇员
   public Emp findEmoById(int id) {
           //判断链表是否为空
       if (head == null) {
           System.out.println("链表为空");
           return null;
      }
       //辅助指针
       Emp curEmp=head;
       while (true) {
           if (curEmp.id == id) {
               break;//这时curEmp就指向要查找的雇员
          }
           //退出
           if (curEmp.next == null) {
               //遍历当前链表没有找到该雇员
               curEmp=null;
               break;
          }
           curEmp=curEmp.next;
      }
       return curEmp;
  }
  }

 

image-20211004113507181

代码亲测有效

树结构

树结构基础

优点: 能提高数据存储 读取的效率

二叉树遍历及删除(重点)

概念:每个节点最多只能有两个子节点的一种形式称为二叉树 子节点分为左节点和右节点

前序遍历:先输出父节点 再遍历左子树和右子树

中序遍历:先遍历左子树 再输出父节点 再遍历右子树

后序遍历:先遍历左子树 再遍历右子树 最后输出父节点

public class BinaryTreeDmo {
   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, "吴用");
       //创建
       root.setLeft(node2);
       root.setRight(node3);
       node3.setRight(node4);
       binaryTree.setRoot(root);
       //
       System.out.println("前序遍历");//1 2 3 4
       binaryTree.preOrder();

       System.out.println("中序遍历");//2 1 3 4
       binaryTree.infixOrder();

       System.out.println("后序遍历");//2 4 3 1
       binaryTree.postOrder();
       //前序遍历
//       System.out.println("前序遍历方式");
//       HeroNode resNode = binaryTree.preOrderSearch(4);
//       if (resNode != null) {
//           System.out.printf("找到了 信息为no=%d, name=%s", resNode.getNo(), resNode.getName());
//       } else {
//           System.out.printf("没有找到no=%d的人",4);
//       }
       //中序遍历
       //     System.out.println("中序遍历方式");
       //   HeroNode resNode = binaryTree.infixOrderSearch(4);
       // if (resNode != null) {
       //   System.out.printf("找到了 信息为no=%d, name=%s", resNode.getNo(), resNode.getName());
       // } else {
       //   System.out.printf("没有找到no=%d的人",4);
       // }
       //后序遍历
//       System.out.println("后序遍历方式");
//       HeroNode resNode = binaryTree.postOrderSearch(1);
//       if (resNode != null) {
//           System.out.printf("找到了 信息为no=%d, name=%s", resNode.getNo(), resNode.getName());
//       } else {
//           System.out.printf("没有找到no=%d的人", 1);
//       }
//删除节点
       System.out.println("删除前 前序遍历");
       binaryTree.preOrder();//1 2 3 4
       binaryTree.delNode(4);
       System.out.println("删除后 前序遍历");
       binaryTree.preOrder();//1 2     3
  }

}

//定义二叉树
class BinaryTree {
   //根节点
   private HeroNode root;

   public void setRoot(HeroNode root) {
       this.root = root;
  }

   //删除节点
   public void delNode(int no) {
       if (root != null) {
           //只有root一个节点 判断是不是就要删除节点
           if (root.getNo() == no) {
               root = null;
          } else {
               //递归删除
               root.delNode(no);
          }
      } else {
           System.out.println("空树不能删除");
      }
  }

   //前序遍历
   public void preOrder() {
       if (root != null) {
           this.root.preOrder();
      } else {
           System.out.println("二叉树为空 无法遍历");
      }
  }

   //中序遍历
   public void infixOrder() {
       if (root != null) {
           this.root.infixOrder();
      } else {
           System.out.println("二叉树为空 无法遍历");
      }
  }

   //后序遍历
   public void postOrder() {
       if (root != null) {
           this.root.postOrder();
      } else {
           System.out.println("二叉树为空 无法遍历");
      }
  }

   //前序遍历
   public HeroNode preOrderSearch(int no) {

       if (root != null) {
           return root.preOrderSearch(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;
      }
  }
}

//创建节点
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;
  }

   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 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();
      }
       System.out.println(this);
       //向右递归
       if (this.right != null) {
           this.right.postOrder();
      }
       System.out.println(this);
  }

   //前序遍历查找
   public HeroNode preOrderSearch(int no) {
       System.out.println("进入前序遍历");
       //比较当前节点
       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;
      }
       System.out.println("进入中序遍历");
       //若没有找到 就和当前节点比较
       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.right.postOrderSearch(no);
      }
       if (resNode != null) {
           //在左子树找到
           return resNode;
      }
       //若左子树没有找到 则向右递归
       if (this.right != null) {
           resNode = this.right.postOrderSearch(no);
      }
       if (resNode != null) {
           return resNode;
      }
       System.out.println("进入后序遍历");
       //若左右都没找到 就比较当前节点
       if (this.no == no) {
           return this;
      }
       return resNode;

  }
}

顺序存储二叉树

注意:二叉树中编号按0开始

public class ArrBinaryTreeDmo {
   public static void main(String[] args) {
       int arr[] = {1, 2, 3, 4, 5, 6, 7};
       ArrBinaryTree arrBinaryTree = new ArrBinaryTree(arr);
       arrBinaryTree.perOrder(0);//结果为 1 2 4 5 3 6 7

  }
}

//编写ArrBinaryTree 实现顺序存储二叉树遍历
class ArrBinaryTree {
   private int[] arr;

   public ArrBinaryTree(int[] arr) {
       this.arr = arr;
  }

   //编写方法 index 数组的下标
   public void perOrder(int index) {
       if (arr == null || arr.length == 0) {
           System.out.println("数组为空 不能遍历");
      }
       //输出元素
       System.out.println(arr[index]);
       //向左递归遍历
       if ((index * 2 + 1) < arr.length) {
           perOrder(2 * index + 1);
      }
       //向右递归
       if ((index * 2 + 2) < arr.length) {
           perOrder(2 * index + 2);
      }
  }
}

二叉排序树

图示:image-20211006103636614

public class BinarySortTreeDemo {
   public static void main(String[] args) {
       int arr[]={7, 3, 10, 12, 5, 1, 9,2};
       BinarySortTree binarySortTree = new BinarySortTree();
       //循环添加节点到二叉排列树
       for (int i = 0; i < arr.length; i++) {
           binarySortTree.add(new Node(arr[i]));
      }
       //中序遍历
       System.out.println("中序遍历二叉排序树");
       binarySortTree.infixOrder();//1 3 5 7 9 10 12
       //测试删除叶子节点
       binarySortTree.delNode(2);
       System.out.println("删除节点后");
       binarySortTree.infixOrder();
  }
}

//创建二叉排序树
class BinarySortTree {
   private Node root;
   //查找要删除的节点
   public Node search(int value) {
       if (root == null) {
           return null;
      } else {
           return root.search(value);
      }
  }
   //查找父节点
   public Node searchParent(int value) {
       if (root == null) {
           return null;
      } else {
           return root.searchParent(value);
      }
  }
   //删除节点
   public void delNode(int value) {
       if (root == null) {
           return;
      } else {
           //先找到要删除的节点
           Node targetNode=search(value);
           //若没有找到
           if (targetNode == null) {
               return;
          }
           //若只有一个节点
           if (root.left == null && root.right == null) {
               root=null;
               return;
          }
           //找到targetNode父节点
           Node parent=searchParent(value);
           //若要删除的节点是叶子节点
           if (targetNode.left == null && targetNode.right == null) {
               //判断targetNode的父节点是左子节点还是右子节点
               if (parent.left != null && parent.left.value == value) {
                   parent.left=null;
              } else if (parent.right != null && parent.right.value == value) {
                   parent.right=null;
              }
          }
      }
  }
   //添加节点
   public  void add(Node node) {
       if (root == null) {
           root = node;
      } else {
           root.add(node);
      }
  }
   //遍历
   public void infixOrder() {
       if (root != null) {
           root.infixOrder();
      } else {
           System.out.println("二叉树为空 不能遍历");
      }
  }
}
//创建node节点
class Node {
   int value;
   Node left;
   Node right;

   public Node(int value) {
       this.value = value;
  }
//查找要删除的节点
   public Node search(int value) {
       if (value == this.value) {
           return this;
      } else if (value < this.value) {
           //若查找的节点小于当前节点
           //如果左子节点为空
           if (this.left == null) {
               return null;
          }
           return this.left.search(value);
      } else {
           //若查找的节点大于当前节点
           //如果右子节点为空
           if (this.right == null) {
               return null;
          }
           return this.right.search(value);
      }
  }
//查找要删除节点的父节点
   public Node searchParent(int value) {
       if ((this.left != null && this.left.value == value) ||
              (this.right != null && this.right.value == value)) {
           return this;
      } else {
           //若查找的值小于当前节点的值 并且当前节点的左子节点不为空
           if (value < this.value && this.left != null) {
               return this.left.searchParent(value); //向左递归查找
          } else if (value >= this.value && this.right != null) {
               return this.right.searchParent(value);//向右递归查找
          } else {
               return null;//没有找到父节点
          }
      }
  }


   @Override
   public String toString() {
       return "Node{" +
               "value=" + value +
               '}';
  }

   //添加节点的方法
   //递归形式添加节点
   public void add(Node node) {
       if (node == null) {
           return;
      }
       //判断与根节点的大小关系
       if (node.value < this.value) {
           if (this.left == null) {
               this.left = node;
          } else {
               //递归左子树添加
               this.left.add(node);
          }
      } else {//添加的节点的值大于当前的值
               if (this.right == null) {
                   this.right = node;
              } else {
                   this.right.add(node);
              }
      }
  }//中序遍历
       public void infixOrder() {
           if (this.left != null) {
               this.left.infixOrder();
          }
           System.out.println(this);
           if (this.right != null) {
               this.right.infixOrder();
          }
      }
}

 

posted @ 2021-10-06 16:46  抚尘  阅读(26)  评论(0)    收藏  举报