Java数据结构与算法

线性结构:线性表、队列、堆、栈

顺序表

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;
        * */
    }
}

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值