数据结构之字符串、链表、队列、栈、树

一、字符串

public class HuiWenChuan {
    public static void main(String[] args) {
        String str = "A man, a plan, a canal: Panama";
        System.out.println("判断回文串----->>>>>" + isPalindrome(str));
        List<List<String>> lists = partition("aab");
        System.out.println("分割回文串:" + lists);
        int a = StrToInt("-1112");
        System.out.println("把字符串转换成整数----->>>>>" + a);
        boolean flag = wordBreak("leetcode", Arrays.asList("leet","code"));
        System.out.println("单词拆分----->>>>>leetcode返回:" + flag);
        boolean flag1 = wordBreak("applepenapple", Arrays.asList("apple","pen"));
        System.out.println("单词拆分----->>>>>applepenapple返回:" + flag1);
        boolean flag2 = wordBreak("catsandog", Arrays.asList("cats", "dog", "sand", "and", "cat"));
        System.out.println("单词拆分----->>>>>catsandog返回:" + flag2);
    }

    /**
     *  1.验证回文串
     * @param s
     * @return
     */
    public static boolean isPalindrome(String s){
        if (s.length() == 0) {
            return true;
        }
        int l = 0;
        int r = s.length() - 1;
        while (l < r) {
            if (!Character.isLetterOrDigit(s.charAt(l))) {
                l++;
            } else if (!Character.isLetterOrDigit(s.charAt(r))) {
                r--;
            }else {
                if (Character.toLowerCase(s.charAt(l)) != Character.toLowerCase(s.charAt(r))) {
                    return false;
                }
                l++;
                r--;
            }
        }
        return true;
    }

    //回文串,只包含字符串
    public static boolean isPalindroom(String s,int left,int right){
        while (left < right && s.charAt(left) == s.charAt(right)) {
            left++;
            right--;
        }
        return left>=right;
    }

    /**
     * 2.分割回文串
     * https://blog.csdn.net/sunday0904/article/details/70153510
     * @param s
     * @return
     */
    public static List<List<String>> partition(String s) {
        // write your code here
        List<List<String>> result = new ArrayList<List<String>>();
        if(s == null){
            return result;
        }
        List<String> temp = new ArrayList<String>();
        if(s.length() == 0){
            result.add(temp);
            return result;
        }
        search(s , result , temp ,0);
        return result;

    }
    private static void search(String s , List<List<String>> result , List<String> temp , int start){
        if(start == s.length()){
            List<String> p = new ArrayList<String>(temp);
            result.add(p);
            return;
        }
        for(int i = start;i<s.length();i++){
            if(isPartition(s.substring(start , i+1))){
                temp.add(s.substring(start , i+1));
                search(s , result , temp , i+1);
                temp.remove(temp.size() - 1);
            }
        }
    }
    //回文串
    private static boolean isPartition(String temp){
        int i = 0;
        int j = temp.length() - 1;
        while(i<j){
            if(temp.charAt(i) != temp.charAt(j)){
                return false;
            }
            i++;
            j--;
        }
        return true;
    }

    /**
     * 3.把字符串转换成整数
     * @param str
     * @return
     */
    public static int StrToInt(String str) {
        if (str == null || str.length() == 0)
            return 0;
        boolean isNegative = str.charAt(0) == '-';
        int ret = 0;
        for (int i = 0; i < str.length(); i++) {
            char c = str.charAt(i);
            if (i == 0 && (c == '+' || c == '-'))  /* 符号判定 */
                continue;
            if (c < '0' || c > '9')                /* 非法输入 */
                return 0;
            ret = ret * 10 + (c - '0');
        }
        return isNegative ? -ret : ret;
    }

    /**
     * 4.单词拆分
     * @param s 非空字符串 s
     * @param wordDict  一个包含非空单词列表的字典 wordDict
     * @return s 是否可以被空格拆分为一个或多个在字典中出现的单词。
     * https://blog.csdn.net/microopithecus/article/details/88291095
     */
    public static boolean wordBreak(String s, List<String> wordDict) {
        int n=s.length();
        boolean[] dp=new boolean[n+1];
        dp[0]=true;
        for (int i=1;i<=n;i++){
            for (int j = 0; j <i ; j++) {
                if (dp[j]&&wordDict.contains(s.substring(j,i))){
                    dp[i]=true;
                    break;
                }
            }
        }
        return dp[n];

    }

}

二、单链表

链表结构:

public class DataNode {

    public int data;
    public DataNode next;
    public DataNode(int data) {
        this.data = data;
    }
    public int getData() {
        return data;
    }
    public void setData(int data) {
        this.data = data;
    }
    public DataNode getNext() {
        return next;
    }
    public void setNext(DataNode next) {
        this.next = next;
    }

}

链表的初始化:

public class DataChain {
    private DataNode head;

    public DataChain(int size) {
        DataNode head = new DataNode(0);
        DataNode cur = head;
        for(int i=1;i<size;i++) {
            DataNode temp = new DataNode(i);
            cur.setNext(temp);
            cur = temp;
        }
        this.head = head;
    }


    public DataNode getHead() {
        return head;
    }

    public void setHead(DataNode head) {
        this.head = head;
    }

    public static void printChain(DataNode head) {
        StringBuilder sb = new StringBuilder();
        DataNode cur = head;
        sb.append(cur.getData());
        while (null != cur.getNext()) {
            sb.append(" -> ");
            sb.append(cur.getNext().getData());
            cur = cur.getNext();
        }
        System.out.println(sb.toString());
    }

    public static void main(String... strings) {
        DataChain chain = new DataChain(10);
        printChain(chain.getHead());
    }

}

链表反转

public class DataNodeTest {
    public static void main(String[] args) {
        DataChain chain = new DataChain(10);
        DataNode node = reverse1(chain.getHead());
        DataChain.printChain(node);
    }

    /**
     * 通过遍历实现
     * @param node
     * @return
     */
    public static DataNode reverse(DataNode node){
        //如何链表没有元素或者链表只有一个元素,不必要反转,返回链表本身就行。
        if(node == null ||node.next == null){
            return node;
        }

        //当链表超过两个及以上就需要反转
        DataNode pre = null;//用于保存当前节点的前一个节点
        DataNode cur = node;//cur保存当前节点

        while(cur != null){
            DataNode next = cur.next;//获取当前节点的下一个元素
            cur.next = pre;//把当前节点的next指向前一个元素
            pre = cur;//把当前节点改为前一个节点(其实就是前一个元素后移一位)。
            cur = next;//把当前节点的下一个节点改为当前节点(其实就是前一个元素后移一位)。
        }

        //因为反转后pre是第一个节点,所以返回pre.
        return pre;
    }

    /**
     * 通过递归实现
     * @param head
     * @return
     */
    public static DataNode reverse1(DataNode head) {
        if (null == head || null == head.getNext())
            return head;
        DataNode revHead = reverse1(head.getNext());
        head.getNext().setNext(head);
        head.setNext(null);
        return revHead;
    }
}

三、二叉树

树结构:

public class BinaryTree {
    int data;//根节点数据
    BinaryTree left;//左子树
    BinaryTree right;//左子树

    public BinaryTree(int data) {
        this.data = data;
        left = null;
        right = null;
    }

    public void insert(BinaryTree root, int data) {
        if (data > root.data) { // 右子节点
            if (root.right == null) {
                root.right = new BinaryTree(data);
            }else {
                insert(root.right, data);
            }
        }else {
            if (root.left == null) {
                root.left = new BinaryTree(data);
            }else {
                insert(root.left, data);
            }
        }
    }
}

测试代码:

public class BinaryTreeTest {
    public static void main(String[] args) {
        int[] array={12,11,4,7,34,23,56,43,22,11,55,6};
        BinaryTree root = new BinaryTree(array[0]);
        for(int i=1;i<array.length;i++) {
            root.insert(root, array[i]);
        }
        System.out.println("----------前序遍历");
        preOrder(root);
        System.out.println("----------中序遍历");
        inOrder(root);
        System.out.println("----------后序遍历");
        postOrder(root);
    }

    //前序遍历
    private static void preOrder(BinaryTree root) {
        if (root != null) {
            System.out.println("data: " + root.data);
            preOrder(root.left);
            preOrder(root.right);

        }
    }

    //中序遍历
    private static void inOrder(BinaryTree root) {
        if (root != null) {
            inOrder(root.left);
            System.out.println("data: " + root.data);
            inOrder(root.right);
        }
    }

    //后序遍历
    private static void postOrder(BinaryTree root) {
        if (root != null) {
            postOrder(root.left);
            postOrder(root.right);
            System.out.println("data: " + root.data);
        }
    }
}

四、数组实现栈

栈的实现:

public class ArrayStack<T> {
    private static final int DEFAULT_SIZE = 12;
    private T[] mArray;
    private int count;

    public ArrayStack(Class<T> type) {
        this(type, DEFAULT_SIZE);
    }

    public ArrayStack(Class<T> type, int size) {
//        Object array = Array.newInstance(type, 10);//创建一个长度为10的字符串数组,在Java中数组也可以作为Object对象
        mArray = (T[]) Array.newInstance(type, size);//创建数组
        count = 0;
    }

    //入栈
    public void push(T val) {
        mArray[count++] = val;
    }
    //出栈
    public T pop (){
        T ret = mArray[count - 1];
        count--;
        return ret;
    }
    //栈顶元素
    public T peek(){
        return mArray[count - 1];
    }
    //栈大小
    public int size(){
        return count;
    }
    //栈是否为空
    public boolean isEmpty(){
        return count == 0;
    }
    //打印栈元素
    public void print(){
        if (isEmpty()) {
            System.out.printf("stack is Empty\n");
        }

        int i = size() - 1;
        while (i >= 0) {
            System.out.println(mArray[i]);
            i--;
        }
    }

}

测试代码:

public class ArrayStackTest {
    public static void main(String[] args) {
        ArrayStack<String> arrayStack = new ArrayStack<>(String.class);
        arrayStack.push("!");
        arrayStack.push("程序猿");
        arrayStack.push("是");
        arrayStack.push("我");

        arrayStack.print();

        System.out.println("出栈元素:" + arrayStack.pop());

        System.out.println("返回栈顶元素:" + arrayStack.peek());


    }
}

五、数组实现队列

 数组实现队列:

public class ArrayQueue<T> {
    private T[] mArry;
    private int count;

    public ArrayQueue(Class<T> type, int sz) {
        mArry = (T[]) Array.newInstance(type, sz);
        count = 0;
    }

    //队列增加元素
    public void add(T val) {
        mArry[count++] = val;
    }

    //队列返回开头元素
    public T front() {
        return mArry[0];
    }

    //返回栈顶元素
    public T pop() {
        T rer = mArry[0];
        count--;
        for(int i=1;i<count;i++) {
            mArry[i - 1] = mArry[i];
        }
        return rer;
    }
    //返回队列大小
    public int size(){
        return count;
    }
    // 返回“栈”是否为空
    public boolean isEmpty() {
        return size()==0;
    }


}

测试:

public class ArrayQueueTest {
    public static void main(String[] args) {
        ArrayQueue<String> arrayQueue = new ArrayQueue<>(String.class, 10);
        arrayQueue.add("我");
        arrayQueue.add("是");
        arrayQueue.add("程序员");
        arrayQueue.add("!");
        System.out.println("返回队列开头元素:"+arrayQueue.front());
        System.out.println("返回队列栈顶元素:"+arrayQueue.pop());
        System.out.println("返回队列大小:" + arrayQueue.size());


        /*StackForQuene stackForQuene = new StackForQuene();
        stackForQuene.add("我");
        stackForQuene.add("是");
        stackForQuene.add("程序员");
        stackForQuene.add("!");
        System.out.println("返回队列栈顶元素:"+stackForQuene.get());
        System.out.println("返回队列大小:" + stackForQuene.size());*/

    }
}

用栈实现队列:

public class StackForQuene<T> {

    private Stack<T> mIn = null;
    private Stack<T> mOut = null;
    private int count = 0;

    public StackForQuene() {
        mIn = new Stack<T>();
        mOut = new Stack<T>();
        count = 0;
    }

    //对列增加元素
    public void add(T val) {
        while (!mOut.isEmpty()) {
            mIn.push(mOut.pop());
        }
        mIn.push(val);
        count++;
    }

    //获取队列元素
    public  T get() {
        while (!mIn.isEmpty()) {
            mOut.push(mIn.pop());
        }
        count--;
        return mOut.pop();
    }

    //队列大小
    public int size() {
        return count;
    }

    //队列是否为空
    public boolean isEmpty() {
        return size() == 0;
    }
}

 六、双链表

创建双链表:

public class DoubleLink<T> {
    //表头
    private Node<T> head;

    //节点个数
    private int count;

    // 双向链表“节点”对应的结构体
    private class Node<T> {
        public Node pre;
        public Node next;
        public T value;

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

    //构造函数
    public DoubleLink() {
        //表头不存数据
        head = new Node<T>(null, null, null);
        head.pre = head.next = head;
        count = 0;
    }

    public int size() {
        return count;
    }

    public boolean isEmpty(){
        return size() == 0;
    }

    /**获取第index位置的节点*/
    private Node<T> getNode(int index) {
        if (index < 0 || index >= count) {
            throw new IndexOutOfBoundsException();
        }
        //正向查找
        if (index <= count / 2) {
            Node<T> node = head.next;
            for(int i=0;i<index;i++) {
                node = node.next;
            }
            return node;
        }else {
            Node<T> node = head.pre;
            int rindex = count - index - 1;
            for(int i=0;i<rindex;i++) {
                node = node.pre;
            }
            return node;
        }
    }

    // 获取第index位置的节点的值
    public T get(int index) {
        return getNode(index).value;
    }

    //获取第一个节点的值
    public T geFirst(){
        return getNode(0).value;
    }

    //获取最后一个节点的值
    public T getLast() {
        return getNode(count - 1).value;
    }

    /**将节点插入到第index的位置之前*/
    public void insert(int index, T t) {
        if (index == 0) {
            Node<T> node = new Node<>(t, head, head.next);
            head.next.pre = node;
            head.next = node;
            count++;
        }else {
            Node<T> node = getNode(index);
            Node<T> tNode = new Node<>(t, node.pre, node);
            node.pre.next = tNode;
            node.next = tNode;
            count++;
        }
    }

    //将节点插入第一个节点处
    public void insertFirst(T t) {
        insert(0, t);
    }

    //将节点添加到链表结尾
    public void appendLast(T t){
        Node<T> node = new Node<>(t, head.pre, head);
        head.pre.next = node;
        head.pre = node;
        count++;
    }

    /**删除节点位置*/
    public void del(int index) {
        Node<T> node = getNode(index);
        node.pre.next = node.next;
        node.next.pre = node.pre;
        node = null;
        count--;
    }

    // 删除第一个节点
    public void deleteFirst(){
        del(0);
    }
    //// 删除第一个节点
    public void deleteLast(){
        del(count - 1);
    }
}

测试代码:

public class DoubleLinkTest {
    public static void main(String[] args) {
        testInteger();
        testString();
        testStudent();
    }

    //操作int
    private static void testInteger() {
        int[] arr = {10, 20, 30, 40};
        DoubleLink<Integer> link = new DoubleLink<Integer>();
        link.insert(0, 20);
        link.appendLast(10);
        link.insertFirst(30);
        for(int i=0;i<link.size();i++) {
            System.out.println(link.get(i));
        }
    }
    //操作字符串
    private static void testString() {
        String[] sarr = {"ten", "twenty", "thirty", "forty"};
        DoubleLink<String> link = new DoubleLink<String>();
        link.insert(0,  sarr[1]);
        link.appendLast( sarr[0]);
        link.insertFirst( sarr[2]);
        for(int i=0;i<link.size();i++) {
            System.out.println(link.get(i));
        }
    }

    //操作对象
    private static void testStudent() {
        String[] sarr = {"ten", "twenty", "thirty", "forty"};
        DoubleLink<Student> link = new DoubleLink<Student>();
        link.insert(0,  Student.students[1]);
        link.appendLast( Student.students[0]);
        link.insertFirst( Student.students[2]);
        for(int i=0;i<link.size();i++) {
            System.out.println(link.get(i));
        }
    }


    private static class Student{
        private int id;
        private String name;

        public Student(int id, String name) {
            this.id = id;
            this.name = name;
        }

        @Override
        public String toString() {
            return "Student{" +
                    "id=" + id +
                    ", name='" + name + '\'' +
                    '}';
        }
        private static Student[] students = new Student[]{
                new Student(10, "sky"),
                new Student(10, "jody"),
                new Student(10, "vic"),
                new Student(10, "dan")
        };
    }
}

 

posted @ 2019-07-18 23:44  何其小静  阅读(554)  评论(0编辑  收藏  举报