开始简单算法

算法

六大排序算法

package com.GWL.test;

import java.lang.reflect.Array;
import java.util.Arrays;

/**
* 排序算法:
* 简单排序:冒泡排序、选择排序、插入排序
* 高级排序:希尔排序、归并排序、快速排序
* */
public class TestComparable {
    public static void main(String[] args) {

        kuaiSuD();
    }

    //    冒泡排序算法
    public static void maoPao() {
//将最大数放最后面
        int[] ints = {5, 4, 8, 1, 4, 8, 7, 9};
        int s;
        for (int i = ints.length - 1; i > 0; i--) {
            for (int j = 0; j < i; j++) {
                if (ints[j] > ints[i]) {
                    s = ints[j];
                    ints[j] = ints[i];
                    ints[i] = s;
                }
            }
        }
        System.out.println(Arrays.toString(ints) + "冒泡排序:时间复杂度:O(n^2)");
    }

    //    选择排序算法
    public static void xuanZhe() {
        int[] arr = {0, 4, 8, 1, 3, 2, 11, 9};
//        用于记录最小值的下标
        int min = 0;
        int x;
        for (int i = 0; i < arr.length - 1; i++) {
            min = i;
            for (int j = i + 1; j < arr.length; j++) {
                if (arr[min] > arr[j]) {
                    min = j;
                }
            }
//            最小值放在左边
            x = arr[i];
            arr[i] = arr[min];
            arr[min] = x;
        }
        System.out.println(Arrays.toString(arr) + "选择排序:时间复杂度:O(n^2)");
    }

    //    插入排序算法
    public static void chaRu() {
        int[] arr = {3, 4, 1, 8, 1, 9, 5, 11, 2, 6};
        int x;
        for (int i = 1; i < arr.length; i++) {
//            老师的
            for (int j = i; j > 0; j--) {
                if (arr[j] < arr[j - 1]) {
                    x = arr[j - 1];
                    arr[j - 1] = arr[j];
                    arr[j] = x;
                } else {
                    break;
                }
            }
//            我的
//            for (int j = i - 1; j >= 0; j--) {
//                if (arr[i] < arr[j]) {
//                    x = arr[i];
//                    arr[i] = arr[j];
//                    arr[j] = x;
//                    i=j;
//                }else {
//                    break;
//                }
//            }
        }
        System.out.println(Arrays.toString(arr) + "插入排序时间复杂度:O(N^2)");
    }

    //    希尔排序,插入排序的优化,分组插入
    public static void xiEr() {
        int[] arr = {3, 4, 1, 8, 1, 9, 5, 11, 2, 6};
//      1、  根据数组的长度确认分组大小
        int h = 1;
        while (h < arr.length / 2) {
            h = 2 * h + 1;
        }
//       2、  排序
        while (h >= 1) {
            int x;
            for (int i = h; i < arr.length; i++) {
                for (int j = i; j >= h; j -= h) {
                    if (arr[j] < arr[j - h]) {
                        x = arr[j - h];
                        arr[j - h] = arr[j];
                        arr[j] = x;
                    } else {
                        break;
                    }
                }
            }
            System.out.println(Arrays.toString(arr));
            h = (int) h / 2;
        }

    }

    //    归并排序算法调用
    public static void guiBing() {
        int[] arr = {3, 4, 1, 8, 9, 5, 11, 2, 6, 3, 21, 4, 5};
        int[] str = new int[arr.length];
        guiBin(arr, 0, arr.length - 1, str);
        System.out.println(Arrays.toString(str) + "归并算法时间复杂度:O(nlogn)");
    }

    //    归并算法主体
    public static void guiBin(int[] arr, int x, int y, int[] str) {
//        数据数组arr,辅助数组str;
        int z;
        if (x >= y) {
//            递归出口,当分组成员个数为一时,结束递归
            return;
        } else {
//            当分组成员个数大于二都要分组
            z = (x + y) / 2;
            guiBin(arr, x, z, str);
            guiBin(arr, z + 1, y, str);
//            先定义三个指针,分别指向需要合并的两个分组的头元素,以及辅助数组的起始对应位置
            int a = x;
            int b = z + 1;
            int i = x;
//            当每一组的指针没溢出时,依次比较两组的元素大小,并将小的存入辅助数组
            while (a <= z && b <= y) {
                if (arr[a] > arr[b]) {
                    str[i++] = arr[b++];
                } else {
                    str[i++] = arr[a++];
                }
            }
//            其中一组先结束则遍历另一组直接顺序存入
            while (a <= z) {
                str[i++] = arr[a++];
            }
            while (b <= y) {
                str[i++] = arr[b++];
            }
//            此时辅助数组中的元素已经排序完成,现在将数据辅助回原始数组
            for (int j = x; j <= y; j++) {
                arr[j] = str[j];
            }

        }
    }

//    快速排序算法调用
    public static void kuaiSuD(){
        int[] arr = {3, 4, 1, 8, 9, 5, 11, 2, 6, 3, 21, 4, 5};
        kuaiSu(arr, 0, arr.length - 1);
        System.out.println(Arrays.toString(arr) + "快速算法时间复杂度:O(nlogn)");
    }

    //    快速排序算法
    public static void kuaiSu(int[] arr, int x, int y) {
//        递归出口,分组至但个元素结束结束
        if (x >= y) {
            return;
        } else {
//            记住第一份元素的值,作为分界点,两头指针依次内移
            int s = arr[x];
            int a = x;
            int b = y + 1;
            while (true) {
//                右边指针遇到小于分界点元素是停止移动
                while (arr[--b] > s) {
                    if (a >= b) {
                        break;
                    }
                }
//                左边指针遇到大于分界点的元素时停止右移
                while (arr[++a] < s) {
                    if (a >= b) {
                        break;
                    }
                }
//               若两指针相遇着结束移动 ,否则交换两指针的数值
                if (a >= b) {
                    break;
                } else {
                    int i = arr[b];
                    arr[b] = arr[a];
                    arr[a] = i;
                }
            }
//           因为有指针停留处,元素一定小于分界点,交换右指针与分界点的数值
            int e = arr[b];
            arr[b] = s;
            arr[x] = e;
//            分界点两边再次分组
            kuaiSu(arr, x, b - 1);
            kuaiSu(arr, b + 1, y);
        }
    }

}

链表实现LinkList()

package com.GWL.suanFa;

import org.w3c.dom.Node;

import java.util.Iterator;
//继承Iterable<T>可用于遍历链表
public class LinkList<T> implements Iterable<T> {
    //    头结点
    public Node head;
    //    链表长度
    private int N;


    //节点
    private class Node {
        //        节点数值
        T item;
        //        下一节点
        Node next;

        public Node(T item, Node next) {
            this.item = item;
            this.next = next;
        }
    }

    public LinkList() {
        this.head = new Node(null, null);
        this.N = 0;
    }

    //链表长度
    public int length() {
        return this.N;
    }

    //添加链表元素
    public void add(T item) {
        Node pre = head;
        for (int i = 0; pre.next != null; i++) {
            pre = pre.next;
        }
        pre.next = new Node(item, null);
        this.N++;
    }

    //通过索引查找对应元素
    public T selectOne(int n) {
        Node pre = head;
        for (int i = 0; i < n; i++) {
            pre = pre.next;
        }
        T t = pre.next.item;
        return t;

    }

    //    通过索引删除对应元素
    public T deleteOne(int n) {
        Node pre = head;
        for (int i = 0; i < n; i++) {
            pre = pre.next;
        }
        Node s = pre.next;
        pre.next = s.next;
        N--;
        return s.item;
    }

    //在指定位置插入新内容
    public void insertOne(int n, T s) {
        Node pre = head;
        for (int i = 0; i < n; i++) {
            pre = pre.next;
        }
        Node ing = new Node(s, pre.next);
        pre.next = ing;
        N++;
    }

    //    继承Iterable<T>,并重写方法,再继承Iterator<T>重写两个方法,就可以for循环遍历了
    @Override
    public Iterator<T> iterator() {
        return new ing();
    }

    private class ing implements Iterator {
        private LinkList.Node n;

        public ing() {
            this.n = head;
        }

        @Override
        public boolean hasNext() {
            return n.next != null;
        }

        @Override
        public Object next() {
            n = n.next;
            return n.item;
        }
    }

    //    链表反转
    public void resti() {
        if (N == 0) {
            return;
        } else {
            rest(head.next);
        }
    }

    //节点反转递归部分
    public Node rest(Node n) {
//        出口,原尾结点成为新头结点
        if (n.next == null) {
            head.next = n;
            return n;
        } else {
//            当前节点转为原上一节点的next节点
            rest(n.next).next = n;
//            原头结点转为尾结点
            n.next = null;
            return n;
        }
    }

}

链表实现HashMap<key,value>()

package com.GWL.suanFa;

import org.w3c.dom.Node;

public class HashMap<key, value> {
    public Node head;
    public int N;

    public class Node {
        public key key;
        public value value;
        public Node next;

        public Node(key key, value value, Node next) {
            this.key = key;
            this.value = value;
            this.next = next;
        }
    }

    public HashMap() {
        this.head = new Node(null, null, null);
        this.N = 0;
    }

    public void put(key key, value value) {
        Node n = head;
        while (n.next != null) {
            n = n.next;
            if (key.equals(n.key)) {
                n.value = value;
                return;
            }

        }
//        这里头处加
        head.next = new Node(key, value, head.next);
        N++;
    }

    public int size() {
        return N;
    }

    public value getValue(key key) {

        Node n = head;
        while (n.next != null) {
            n = n.next;
            if (key.equals(n.key)) {
                return n.value;
            }

        }
        return null;x`
    }
}

链表实现树tree

package com.GWL.suanFa;

import org.w3c.dom.Node;

import java.util.Collection;
import java.util.LinkedList;
import java.util.Queue;

public class BinaryTree<key extends Comparable<key>, value> {
    private Node root;
    private int N;

// 创建节点内部类
    private class Node {
        public key key;
        public value value;
        public Node left;
        public Node right;


        public Node(key key, value value, Node left, Node right) {
            this.key = key;
            this.value = value;
            this.left = left;
            this.right = right;
        }

    }

    public BinaryTree() {
        this.root = null;
        this.N = 0;
    }

    public int length() {
        return N;
    }
//添加数据
    public void put(key key, value value) {
        this.root = put(root, key, value);

    }

    private Node put(Node x, key key, value value) {
        if (x == null) {
            N++;
            return new Node(key, value, null, null);
        } else {
            int a = key.compareTo(x.key);
            if (a > 0) {
                x.right = put(x.right, key, value);
            } else if (a < 0) {
                x.left = put(x.left, key, value);
            } else {
                x.value = value;
            }
            return x;
        }
    }
//    通过key获取值
    public value getValue(key key) {
        return getValue(root, key);
    }

    private value getValue(Node x, key key) {
        if (x == null) {
            return null;
        }
        int a = key.compareTo(x.key);
        if (a == 0) {
            return x.value;
        } else if (a < 0) {
            return getValue(x.left, key);
        } else {
            return getValue(x.right, key);
        }
    }

//    通过key删除节点;将
    public void deleteByKey(key key) {
        deleteByKey(root, key);

    }

    private Node deleteByKey(Node x, key key) {
        if (x == null) {
            return null;
        }
        int a = key.compareTo(x.key);
        if (a > 0) {
            x.right = deleteByKey(x.right, key);
            return x;
        } else if (a < 0) {
            x.left = deleteByKey(x.left, key);
            return x;
        } else {
            {
//            此时X为需要删除的那个节点
//                若其左节点为空,直接返回右节点
                if (x.left == null) {
                    N--;
                    return x.right;
                }
//                若其右节点为空,直接返回左节点
                if (x.right == null) {
                    N--;
                    return x.left;
                }
//            若左右节点都不为空,找到右子树中最小值,即右子树中最左的节点,替换被删除的节点的位置                
                Node n = x.right;
                Node y = null;
                if (n.left == null) {
                    n.left = x.left;
                } else {
//                找到最后一个左节点为空的节点,将其右节点赋值为其父节点的左节点
                    while (n.left != null) {
                        y = n;
                        n = n.left;
                    }
                    y.left = n.right;
                     //替换被删除的节点的位置 
                    n.left = x.left;
                    n.right = x.right;
                }
                N--;
                return n;
            }
        }
    }

    //    树的最大深度
    public int zuiShen() {
        return zuiShen(root);
    }

    private int zuiShen(Node n) {
        if (n == null) {
            return 0;
        }
        int x = zuiShen(n.left);
        int y = zuiShen(n.right);
        return x > y ? x + 1 : y + 1;
    }

    //    中序遍历、前序遍历、后序遍历
    public Collection<String> zhong() {
        //此为队列,可用链表实现,先进先出
        //通过控制每个节点的值存入队列的顺序,控制值出队列的顺序,实现前、中、后遍历
        Queue<String> strings = new LinkedList<>();
        zhong(root, strings);
        return strings;
    }

    private void zhong(Node n, Queue<String> strings) {
        if (n == null) {
            return;
        }

        if (n.left != null) {
            zhong(n.left, strings);
        }
//        数据存入列队,这一行放中间就是中序遍历
        strings.add(String.valueOf(n.key));

        if (n.right != null) {
            zhong(n.right, strings);
        }
    }
}

链表实现红黑树

每个节点都有一个键值对存储该节点与其父节点的链接颜色,1、根节点总为黑色,2、红色链接在左边,3、红色链接不能连续的红色,而刚添加的一个节点其与父节点的链接为红色,如果时添加右子树,为了防止红色在右边,需要左旋,

package com.GWL.suanFa;

import org.w3c.dom.Node;

public class RedBlackTree<key extends Comparable<key>, value> {
    private Node root;
    private int N;
    private static final boolean RED = true;
    private static final boolean BLACK = false;


    private class Node {
        public key key;
        public value value;
        public Node left;
        public Node right;
        public boolean color;

        public Node(key key, value value, Node left, Node right, boolean color) {
            this.key = key;
            this.value = value;
            this.left = left;
            this.right = right;
            this.color = color;
        }
    }

    public int length() {
        return N;
    }

    private boolean isRed(Node n) {
        if (n == null) {
            return false;
        }
        return n.color == RED;
    }

    //    左旋
    private Node leftZhuan(Node x) {
        Node y = x.right;
        x.right = y.left;
        y.left = x;
        y.color = x.color;
        x.color = BLACK;
        return y;
    }

    //    右旋
    private Node rightZhuan(Node x) {
        Node y = x.left;
        x.left = y.right;
        y.right = x;
        y.color = x.color;
        x.color = RED;
        return y;
    }

    //    颜色反转
    private void colorZhuan(Node x) {
        x.right.color = BLACK;
        x.left.color = BLACK;
        x.color = RED;
    }

    public void put(key key, value value) {
        root = put(root, key, value);
        root.color = BLACK;
    }

    private Node put(Node x, key key, value value) {
        if (x == null) {
            N++;
            return new Node(key, value, null, null, RED);
        }
        int a = key.compareTo(x.key);
        if (a > 0) {
            x.right = put(x.right, key, value);
        } else if (a < 0) {
            x.left = put(x.left, key, value);
        } else {
            x.value = value;
        }
//        进行左旋:当前节点的左节点为黑色,右节点为红色
        if (isRed(x.right) && !isRed(x.left)) {
            x = leftZhuan(x);
        }
//        进行右旋:当前左节点和左节点的左节点都为红色
        if (isRed(x.left) && isRed(x.left.left)) {
            x = rightZhuan(x);
        }
//        颜色反转:当前节点的左右节点都为红色
        if (isRed(x.right) && isRed(x.left)) {
            colorZhuan(x);
        }

        return x;
    }

    //    通过key获取值
    public value getValue(key key) {
        return getValue(root, key);
    }

    private value getValue(Node x, key key) {
        if (x == null) {
            return null;
        }
        int a = key.compareTo(x.key);
        if (a > 0) {
            return getValue(x.right, key);
        } else if (a < 0) {
            return getValue(x.left, key);
        } else {
            return x.value;
        }
    }
}

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值