线性结构:线性表、队列、堆、栈
顺序表
public class SequenceList<T> implements Iterable<T> {
//存储元素的数组
private T[] eles;
//记录当前顺序表中的元素个数
private int N;
//构造方法
public SequenceList(int capacity) {
//初始化数组
this.eles= (T[]) new Object[capacity];
//初始化长度
this.N=0;
}
//将一个线性表置为空表
public void clear(){
this.N=0;
}
//判断当前线性表是否为空表
public boolean isEmpty(){
return N==0;
}
//获取线性表的长度
public int length(){
return N;
}
//获取指定位置的元素
public T get(int i){
return eles[i];
}
//向线性表中添加元素
public void insert(T t){
if(N==eles.length){
resize(2*eles.length);
}
eles[N++]=t;
}
//指定位置插入指定元素
public void insert(int i,T t){
if(N==eles.length){
resize(2*eles.length);
}
//i之后的元素后移一位
for(int index=N;index>i;index--){
eles[index]=eles[index-1];
}
//把元素插入指定位置i
eles[i]=t;
//元素总数加一
N++;
}
//删除指定位置的元素,并返回元素
public T remove(int i){
T current=eles[i];
//i之后的元素前移一位
for(int index=i+1;index<=N-1;index++){
eles[index]=eles[index+1];
}
N--;
if(N<eles.length/4){
resize(eles.length/2);
}
return current;
}
//查找元素第一次出现的位置
public int indexOf(T t){
for(int i=0;i<N;i++){
if(eles[i].equals(t)){
return i;
}
}
return -1;
}
//根据参数newsize,重置eles的大小
public void resize(int newsize){
//定义一个临时数组,指向原数组
T[] temp=eles;
//创建新数组
eles=(T[])new Object[newsize];
//把原数组的数据拷贝到新数组即可
for(int i=0;i<N;i++){
eles[i]=temp[i];
}
}
@Override
public Iterator<T> iterator(){
return new SIterator();
}
private class SIterator implements Iterator{
public int cusor;
public SIterator(){
this.cusor=0;
}
@Override
public boolean hasNext() {
return cusor<N;
}
@Override
public Object next() {
return eles[cusor++];
}
}
}
测试:
public class TestSquence {
public static void main(String[] args) {
//创一个线性表
SequenceList<String> s=new SequenceList<>(10);
//插入数据
s.insert("威少");
s.insert("杜兰特");
s.insert("哈登");
s.insert("威金斯");
s.insert("杜兰特");
for (String s1 : s) {
System.out.println(s1);
}
//判断当前线性表是否为空表
boolean empty = s.isEmpty();
System.out.println("是否是空表:"+empty);
//获取线性表的长度
int length = s.length();
System.out.println("线性表的长度:"+length);
//获取指定位置的元素
String s1 = s.get(3);
System.out.println(s1);
//向线性表中添加元素
s.insert("麦迪");
//指定位置插入指定元素
s.insert(1,"朱琳");
//删除指定位置的元素,并返回元素
String remove = s.remove(1);
System.out.println("删除的元素是:"+remove);
//查找元素第一次出现的位置
int i = s.indexOf("杜兰特");
System.out.println("杜兰特第一次出现的位置是:"+i);
//将一个线性表置为空表
s.clear();
//获取线性表的长度
int length1 = s.length();
System.out.println("线性表的长度:"+length);
}
}
链表
https://blog.csdn.net/qq_34488912/article/details/108838574
队列
数组模拟队列
package 队列;
public class ArrayQueue {
private int maxSize;//数组的最大容量
private int front;//队列头的前一个位置
private int rear;//队列尾
private int[] arr;
//构造队列
public ArrayQueue(int arrMaxSize){
maxSize=arrMaxSize;
arr=new int[maxSize];
front=-1;//队列头的前一个位置
rear=-1;
}
//判断队列是否满
public boolean isFull(){
return rear==maxSize-1;
}
//判断队列是否空
public boolean isEmpty(){
return rear==front;
}
//添加数据到队列
public void addQueue(int value){
if(isFull()){
System.out.println("队列满!");
return;
}
rear++;
arr[rear]=value;
}
//数据出队列
public int getQueue(){
if(isEmpty()){
throw new RuntimeException("队列为空,没有数据!");
}
front++;
return arr[front];
}
//遍历数据并显示
public void showQueue(){
if(isEmpty()){
System.out.println("队列空,没有数据显示!");
return;
}
for (int i = front+1; i < arr.length; i++) {
System.out.println(arr[i]);
}
}
//显示队列的头数据
public int showHead(){
if(isEmpty()){
throw new RuntimeException("没有数据,头为空!");
}
return arr[front+1];
}
}
数组实现环形队列
package 队列;
public class CircleQueue {
private int maxSize;//数组的最大容量
private int front;//队列头
private int rear;//队列尾的后一个位置
private int[] arr;
//构造队列
public CircleQueue(int arrMaxSize){
maxSize=arrMaxSize;
arr=new int[maxSize];
}
//判断队列是否满
public boolean isFull(){
return (rear+1)%maxSize==front;
}
//判断队列是否空
public boolean isEmpty(){
return rear==front;
}
//添加数据到队列
public void addQueue(int value){
if(isFull()){
System.out.println("队列满!");
return;
}
arr[rear]=value;
rear=(rear+1)%maxSize;
}
//数据出队列
public int getQueue(){
if(isEmpty()){
throw new RuntimeException("队列为空,没有数据!");
}
int value=arr[front];
front=(front+1)%maxSize;
return value;
}
//遍历队列数据并显示
public void showQueue(){
if(isEmpty()){
System.out.println("队列空,没有数据显示!");
return;
}
for (int i = front; i < front+size(); i++) {
System.out.println(arr[i%maxSize]);
}
}
//求当前队列的有效数据个数
public int size(){
return (rear+maxSize-front)%maxSize;
}
//显示队列的头数据
public int showHead(){
if(isEmpty()){
throw new RuntimeException("没有数据,头为空!");
}
return arr[front];
}
}
栈
用数组模拟栈
package 栈;
public class ArrayStack {
private int maxSize;
private int[] stack;//数组模拟栈
private int top=-1;
public ArrayStack(int maxSize) {
this.maxSize = maxSize;
stack=new int[this.maxSize];
}
//栈满
public boolean isFull(){
return top==maxSize-1;
}
//栈空
public boolean isEmpty(){
return top==-1;
}
//入栈
public void push(int value){
if(isFull()){
System.out.println("栈满");
return;
}
top++;
stack[top]=value;
}
//出栈
public int pop(){
if(isEmpty()){
throw new RuntimeException("栈空,没有数据");
}
int temp=stack[top];
top--;
return temp;
}
//遍历
public void show(){
if(isEmpty()){
System.out.println("栈为空");
}
for(int i=top;i>=0;i--)
System.out.println(stack[i]);
}
}
堆
排序
1.冒泡排序
最直接的实现方式
public class bulble {
public static void main(String[] args) {
int arr[]={3,9,-1,10,20};
System.out.println("排序前"+ Arrays.toString(arr));
for (int i = 0; i < arr.length-1; i++) {
for (int j = 0; j <arr.length-j-1; j++) {
int temp=0;
if (arr[j]>arr[j+1]){
temp=arr[j];
arr[j]=arr[j+1];
arr[j+1]=temp;
}
}
}
System.out.println("排序后"+ Arrays.toString(arr));
}
}
优化:加一个flag,如果已经有序,则退出循环
public class bulble1 {
public static void main(String[] args) {
int arr[]={3,9,-1,10,20};
bulblesort(arr);
System.out.println(Arrays.toString(arr));
}
public static void bulblesort(int[] arr){
int temp=0;
boolean flag=false;
for (int i = 0; i < arr.length-1; i++) {
for (int j = 0; j <arr.length-j-1; j++) {
if (arr[j]>arr[j+1]){
flag=true;
temp=arr[j];
arr[j]=arr[j+1];
arr[j+1]=temp;
}
}
//第某轮结束时,flag=false,证明未进入内循环,已经有序,退出
if (flag=false){
break;
}else {
flag=false;
}
}
}
}
测试80000个数据的运行时间:
public class bulble2 {
public static void main(String[] args) {
int arr[]=new int[80000];
for (int i = 0; i < 80000; i++) {
arr[i]=(int)(Math.random()*8000000);
}
long startTime = System.currentTimeMillis(); //获取开始时间
bulblesort(arr); //测试的代码段
long endTime = System.currentTimeMillis(); //获取结束时间
System.out.println("程序运行时间:" + (endTime - startTime) + "ms"); //输出程序运行时间
/* System.out.println(System.currentTimeMillis());
bulblesort(arr);
System.out.println(System.currentTimeMillis());*/
//System.out.println(Arrays.toString(arr));
}
public static void bulblesort(int[] arr){
int temp=0;
boolean flag=false;
for (int i = 0; i < arr.length-1; i++) {
for (int j = 0; j <arr.length-j-1; j++) {
if (arr[j]>arr[j+1]){
flag=true;
temp=arr[j];
arr[j]=arr[j+1];
arr[j+1]=temp;
}
}
if (!flag){
break;
}else {
flag=false;
}
}
}
}
另一种思路:写成API接口:
public class BulbleSort {
//传入实现Comparable接口的类的数组
public static void sort(Comparable[] a){
for(int i=a.length-1;i>0;i--){
for(int j=0;j<i;j++){
if(greater(a[j],a[j+1])){
exch(a,j,j+1);
}
}
}
}
private static void exch(Comparable[] a, int i, int j) {
Comparable temp;
temp=a[i];
a[i]=a[j];
a[j]=temp;
}
//判断v是否大于w
private static boolean greater(Comparable v, Comparable w) {
return v.compareTo(w)>0;
}
}
public class testBulble {
public static void main(String[] args) {
Integer[] arr={4,5,6,3,2,1};
BulbleSort.sort(arr);
System.out.println(Arrays.toString(arr));
}
}
时间复杂度为:O(n^2)
2.选择排序
public class select {
public static void main(String[] args) {
int arr[]={101,34,119,1};
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(arr[j]<min){
min=arr[j];
minIndex=j;
}
}
if(minIndex!=i){
arr[minIndex]=arr[i];
arr[i]=min;
}
}
System.out.println(Arrays.toString(arr));
}
}
同样可以设计API和测试80000条数据执行时间。
时间复杂度为:O(n^2)
3.插入排序
public class Insert {
public static void main(String[] args) {
int arr[]={101,34,119,1,18,45};
for (int i = 1; i < arr.length; i++) {
for(int j=i;j>0;j--){
if(arr[j]<arr[j-1]){
int temp=arr[j];
arr[j]=arr[j-1];
arr[j-1]=temp;
}else{
break;
}
}
}
System.out.println(Arrays.toString(arr));
}
}
同样可以设计API和测试80000条数据执行时间。
时间复杂度为:O(n^2)
4.希尔排序
public class Hell {
public static void main(String[] args) {
int arr[]={101,34,119,1,18,45};
int h=1;
//定义规则
while (h<arr.length){
h=2*h+1;
}
//排序
while(h>=1){
for (int i = h; i < arr.length; i++) {
for(int j=i;j>=h;j-=h){
if(arr[j]<arr[j-h]){
int temp=arr[j];
arr[j]=arr[j-1];
arr[j-1]=temp;
}else{
break;
}
}
}
h=h/2;
}
System.out.println(Arrays.toString(arr));
}
}
同样可以设计API和测试80000条数据执行时间。
时间复杂度为:O(nlogn)~O(n^2)
5.归并排序
public class Merge {
//定义一个临时表
public static Comparable[] assist;
//整个数组排序
public static void sort(Comparable[] a){
assist =new Comparable[a.length];
int lo=0;
int hi=a.length-1;
sort(a,lo,hi);
}
//分组
public static void sort(Comparable[] a,int lo, int hi){
if(hi<=lo){
return;
}
int mid=lo+(hi-lo)/2;
sort(a,lo,mid);
sort(a,mid+1,hi);
merge(a,lo,mid,hi);
}
//归并
private static void merge(Comparable[] a, int lo, int mid, int hi) {
int i=lo;
int p1=lo;
int p2=mid+1;
while(p1<=mid && p2<=hi){
if(less(a[p1],a[p2])){
assist[i++]=a[p1++];
}else{
assist[i++]=a[p2++];
}
}
while (p1<=mid){
assist[i++]=a[p1++];
}
while (p2<=hi){
assist[i++]=a[p2++];
}
for(int index=lo;index<=hi;index++){
a[index]=assist[index];
}
}
private static void exch(Comparable[] a, int i, int j) {
Comparable temp;
temp=a[i];
a[i]=a[j];
a[j]=temp;
}
//判断v是否大于w
private static boolean less(Comparable v, Comparable w) {
return v.compareTo(w)<0;
}
}
public class Mergetest {
public static void main(String[] args) {
Integer[] arr={4,5,6,3,2,1};
Merge.sort(arr);
System.out.println(Arrays.toString(arr));
}
}
时间复杂度:nlogn。一个临时表,时间换空间。
6.快速排序
分组时,从右往左找比基准值小的,与左指针交换,找不到右指针左移;然后从左往右找,找到比基准值大的,与右指针交换,找不到右移指针。直到左右重合或者左大于右。
public class quicksort {
//测试
public static void main(String[] args) {
int[] arr = {6, 9, 1, 4, 5, 8, 7, 0, 2, 3};
quickSort(arr);
System.out.print(Arrays.toString(arr));
}
//对整个数组排序
public static void quickSort(int[] arr) {
if (arr == null || arr.length <= 1) return;
// 包左不包右
quickSort(arr, 0, arr.length);
}
//重载方法对整个数组排序
private static void quickSort(int[] arr, int low, int high) {
// 只有一个元素的话,则什么都不做。
if (high - low <= 1) return;
// 分区,返回基准值的索引partition
int partition = partition(arr, low, high);
// 递归左右两个分区。
quickSort(arr, low, partition);
quickSort(arr, partition + 1, high);
}
//分区
private static int partition(int[] arr, int low, int high) {
int pivot = arr[low]; // 基准值是第一个元素。
int left = low; // 左指针指向最左侧。
int right = high - 1; // 右指针指向最右侧。
while (left < right) {
// 若右指针大于基准值,则左移。
while (left < right && arr[right] >= pivot) {
right--;
}
arr[left] = arr[right]; // 直到arr[right]小于基准值,放到左边。
// 若左指针小于基准值,则右移。
while (left < right && arr[left] <= pivot) {
left++;
}
arr[right] = arr[left]; // 直到arr[left]大于基准值,放到右边。
}
// 基准值放到正确位置。
arr[left] = pivot;
// 返回基准值的索引。
return left;
}
}
稳定:冒泡排序、插入排序、归并排序
不稳定:选择排序、希尔排序、快速排序
树
结点的度:一个结点含有的子树的个数称为该结点的度
树的度:树种所有结点的度的最大值
树的高度:树中所有结点的最大值
二叉树:度不超过2的树,每个结点最多有两个子节点
满二叉树:每层的结点数都达到最大值,结点总数为2^n-1。
完全二叉树:叶结点只出现在最下层和次下层,并且最下面一层的结点在左边连续,倒数第二层的结点右边连续。
树的创建及前序、中序、后序遍历实现
创建结点
package 树;
//结点
public 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 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);
}
}
创建树:
package 树;
public class BinaryTree {
private HeroNode root;
public HeroNode getRoot() {
return 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("二叉树为空,无法遍历");
}
}
}
测试:
package 树;
public class BinaryTreeDemo1 {
public static void main(String[] args) {
BinaryTree binaryTree=new BinaryTree();
HeroNode root=new HeroNode(1,"宋江");
HeroNode heroNode2=new HeroNode(2,"卢俊义");
HeroNode heroNode3=new HeroNode(3,"吴用");
HeroNode heroNode4=new HeroNode(4,"林冲");
root.setLeft(heroNode2);
root.setRight(heroNode3);
heroNode3.setRight(heroNode4);
binaryTree.setRoot(root);
System.out.println("前序遍历");
binaryTree.preOrder();
System.out.println("=======================");
System.out.println("中序遍历");
binaryTree.infixOrder();
System.out.println("=======================");
System.out.println("后序遍历");
binaryTree.postOrder();
}
}
二叉树前中后序查找结点:
结点类:
package 树;
//结点
public 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 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.left.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;
}
}
package 树;
public class BinaryTree {
private HeroNode root;
public HeroNode getRoot() {
return root;
}
public void setRoot(HeroNode root) {
this.root = root;
}
//前序查找
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;
}
}
}
package 树;
public class BinaryTreeDemo1 {
public static void main(String[] args) {
BinaryTree binaryTree=new BinaryTree();
HeroNode root=new HeroNode(1,"宋江");
HeroNode heroNode2=new HeroNode(2,"卢俊义");
HeroNode heroNode3=new HeroNode(3,"吴用");
HeroNode heroNode4=new HeroNode(4,"林冲");
root.setLeft(heroNode2);
root.setRight(heroNode3);
heroNode3.setRight(heroNode4);
binaryTree.setRoot(root);
//前序查找
HeroNode resNode = binaryTree.preOrderSearch(4);
if(resNode!=null){
System.out.println("找到了编号为"+resNode.getNo()+"的结点:"+resNode.getName());
}else {
System.out.println("未找到编号为:"+resNode.getNo()+"的结点");
}
System.out.println("======================");
//中序查找
HeroNode resNode1 = binaryTree.infixOrderSearch(4);
if(resNode1!=null){
System.out.println("找到了编号为"+resNode1.getNo()+"的结点:"+resNode1.getName());
}else {
System.out.println("未找到编号为:"+resNode1.getNo()+"的结点");
}
System.out.println("======================");
//前序查找
HeroNode resNode2 = binaryTree.postOrderSearch(4);
if(resNode2!=null){
System.out.println("找到了编号为"+resNode2.getNo()+"的结点:"+resNode2.getName());
}else {
System.out.println("未找到编号为:"+resNode2.getNo()+"的结点");
}
}
}
二叉树前中后序删除结点:
顺序存储二叉树遍历
package 树;
public class ArrBinaryTree {
private int[] arr;
public ArrBinaryTree(int[] arr) {
this.arr = arr;
}
public void preOrder(){
this.preOrder(0);
}
public void preOrder(int index){
if(arr==null || arr.length==0){
System.out.println("数组为空");
}
System.out.println(arr[index]);
if((index*2+1)<arr.length){
preOrder(index*2+1);
}
if((index*2+2)<arr.length){
preOrder(index*2+2);
}
}
}
测试
public class ArrBinaryTreeTest {
public static void main(String[] args) {
int[]arr={1,2,3,4,5,6,7};
ArrBinaryTree arrBinaryTree = new ArrBinaryTree(arr);
arrBinaryTree.preOrder();
}
}
线索化二叉树
HeroNode
//结点
public class HeroNode {
private int no;
private String name;
private HeroNode left;
private HeroNode right;
//leftType=1表示指向前驱节点,=0指向左子树,=1指向线索化
private int leftType;
private int rightType;
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 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 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){
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.left.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;
}
//删除节点
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);
}
}
}
ThreadBinaryTree
package 树.线索化二叉树;
public class ThreadBinaryTree {
private HeroNode root;
public HeroNode getRoot() {
return root;
}
public void setRoot(HeroNode root) {
this.root = root;
}
//相当于链表中的头节点
private HeroNode pre=null;
public void threadNodes(){
this.threadNodes(root);
}
//遍历线索化二叉树
public void threadList(){
HeroNode node=root;
while (node!=null){
while (node.getLeftType()==0){
node=node.getLeft();
}
System.out.println(node);
while (node.getRightType()==1){
node=node.getRight();
System.out.println(node);
}
node=node.getRight();
}
}
//将二叉树中序线索化
public void threadNodes(HeroNode node){
if(node==null){
return;
}
//先线索化左子树
threadNodes(node.getLeft());
//再线索化当前节点
//先处理前驱节点
if(node.getLeft()==null){
node.setLeft(pre);
node.setLeftType(1);
}
//再处理后继节点
if(pre!=null && pre.getRight()==null){
pre.setRight(node);
pre.setRightType(1);
}
pre=node;
//最后线索化右子树
threadNodes(node.getRight());
}
}
测试
package 树.线索化二叉树;
public class test {
public static void main(String[] args) {
HeroNode root = new HeroNode(1, "1");
HeroNode node2 = new HeroNode(3, "3");
HeroNode node3 = new HeroNode(6, "6");
HeroNode node4 = new HeroNode(8, "8");
HeroNode node5 = new HeroNode(10, "10");
HeroNode node6 = new HeroNode(14, "14");
root.setLeft(node2);
root.setRight(node3);
node2.setLeft(node4);
node2.setRight(node5);
node3.setLeft(node6);
//测试中序线索化
ThreadBinaryTree threadBinaryTree = new ThreadBinaryTree();
threadBinaryTree.setRoot(root);
threadBinaryTree.threadNodes();
//测试,以10号节点测试
HeroNode left = node5.getLeft();
HeroNode right = node5.getRight();
System.out.println(left);
System.out.println(right);
threadBinaryTree.threadList();
}
}
堆排序
package 树.堆排序;
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;
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));
}
//将以i为根节点的子树调整为大顶堆,{4,6,8,5,9}->{4,9,8,5,6}
public static void adjustHeap(int[] arr,int i,int length){
int temp=arr[i];
for(int k=2*i+1;k<length;k=2*k+1){
if(k+1<length && arr[k]<arr[k+1]){
k++;
}
if(arr[k]>temp){
arr[i]=arr[k];
i=k;//循环,继续比较
}else{
break;
}
}
//此时,已经将以i为父节点的树调整为大顶堆
arr[i]=temp;
/*
*
整个过程如下:
temp=arr[i];
arr[i]=arr[k];
i=k;
arr[i]=arr[k]=temp;
* */
}
}