数据结构之字符串、链表、队列、栈、树
一、字符串
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") }; } }
程序员的眼里,不止有代码和bug,还有诗与远方和妹子!!!