目录
Java 数据结构之栈、队列
实现基于数组的栈
package step1; import java.util.NoSuchElementException; /** * Created by sykus on 2018/1/26. */ public class MyStack<T> { private T[] S; private int top;//栈顶元素下标,初始为-1 public MyStack() { this(1); } public MyStack(int capacity) { S = (T[]) new Object[capacity]; top = -1; } /** * 入栈操作,把item压入栈中 * * @param item */ public void push(T item) { int len = S.length; if (top == len - 1) { resize(2 * len); } /********** Begin *********/ S[++top] = item; /********** End *********/ } /** * 返回栈顶元素并从栈中移除 * * @return */ public T pop() { if (isEmpty()) { throw new NoSuchElementException("栈为空!"); } /********** Begin *********/ T val = S[top--]; return val; /********** End *********/ } /** * 判断栈是否为空 * * @return */ public boolean isEmpty() { if (top < 0) return true; else return false; } /** * 动态扩展数组大小 * * @param capacity */ private void resize(int capacity) { assert capacity > top; T[] tmp = (T[]) new Object[capacity]; for (int i = 0; i <= top; i++) { tmp[i] = S[i]; } S = tmp; } }
实现基于链表的栈package step2; import java.util.NoSuchElementException; /** * Created by sykus on 2017/12/29. */ public class MyStack<E> { private Node<E> head;//头结点 private Node<E> top;//栈顶 private int size;//栈中元素个数 public MyStack() { head = new Node<E>(); head.next = null; top = null;//栈顶初始化为null size = 0; } /** * 把item压入栈中 * * @param item */ public void push(E item) { /********** Begin *********/ Node<E> newNode = new Node<E>(); newNode.item = item; newNode.next = head.next; head.next = newNode; top = newNode; ++size; /********** End *********/ } /** * 返回它栈顶元素并删除 */ public E pop() { if (isEmpty()) throw new NoSuchElementException("栈为空!"); /********** Begin *********/ Node<E> node = top; top = top.next; head.next = top; node.next = null; --size; return node.item; /********** End *********/ } /** * 返回栈中元素个数 * * @return */ public int size() { return size; } /** * 判断一个栈是否为空 * * @return */ public boolean isEmpty() { return (null == head); } //链表结点内部类 private static class Node<E> { private E item; private Node<E> next; } }
基于数组的队列package step3; /** * Created by zengpeng on 2018/1/30. */ public class MyQueue<T> { private T[] Q; private int head; private int tail; private int size; public MyQueue() { this(1); } public MyQueue(int capacity) { Q = (T[]) new Object[capacity]; size = 0; head = tail = 0; } /** * 入队操作 * * @param item */ public void enqueue(T item) { /********** Begin *********/ Q[tail] = item; tail = (tail + 1) % Q.length; ++size; /********** End *********/ } /** * 出队操作 * * @return */ public T dequeue() { /********** Begin *********/ T val = Q[head]; head = (head + 1) % Q.length; --size; return val; /********** End *********/ } /** * 判断队列是否为空 * @return */ public boolean isEmpty() { return (head == tail) && (size < Q.length); } public int size() { return size; } }
基于链表的队列package step4; import java.util.NoSuchElementException; /** * Created by sykus on 2017/12/29. */ public class MyQueue<T> { private Node<T> head;// 头结点,不存数据 private Node<T> front;//指向队头结点 private Node<T> tail;//指向队尾结点 private int size; public MyQueue() { head = new Node<T>(); front = tail = null; size = 0; } /** * 入队 * * @param item */ public void enqueue(T item) { /********** Begin *********/ Node<T> oldTail = tail; Node<T> newNode = new Node<T>(); newNode.item = item; newNode.next = null; if (null == front) {//空队列 head.next = newNode; front = newNode; } else { oldTail.next = newNode; } tail = newNode; ++size; /********** End *********/ } /** * 出队 * * @return */ public T dequeue() { if (isEmpty()) throw new NoSuchElementException("队列为空!"); /********** Begin *********/ T val = front.item; head.next = front.next; front.next = null; front = head.next;//此时队头为后继结点 --size; if (null == head.next) {//出队的是队列中的最后一个元素 front = tail = null; } return val; /********** End *********/ } /** * 返回队列中元素数量 * * @return */ public int size() { return size; } /** * 判断一个队列是否为空 * * @return */ public boolean isEmpty() { return (front == null); } /** * 链表结点内部类 */ private static class Node<E> { private E item; private Node<E> next; } }
Java数据结构-线性表的设计与实现
顺序表的实现之增删功能
package step1; /** * Created by zengpeng on 2017/12/25. */ public class MyArrayList { private int[] elements;//元素 private int size;//List中当前的元素个数 public MyArrayList() { this(1);//List默认大小为1 } /** * 按指定大小capacity构造List * * @param capacity List初始化时的大小 */ public MyArrayList(int capacity) { elements = new int[capacity]; size = 0; } /** * 返回List中元素的个数 * * @return */ public int size() { return size; } /** * 添加一个元素到末尾 * * @param item */ public void Add(int item) { int len = elements.length; if (size == len - 1) { resize(2 * len); } /********** Begin *********/ elements[size++] = item; /********** End *********/ } /** * 添加一个元素到指定位置index * * @param index * @param item */ public void Add(int index, int item) { validateRangeForAdd(index); int len = elements.length; if (size == len - 1) { resize(2 * len); } /********** Begin *********/ for (int i = size; i > index; i--) { elements[i] = elements[i - 1]; } elements[index] = item; size++; /********** End *********/ } /** * 删除指定位置index的元素,并返回被删除的元素 * * @param index * @return */ public int remove(int index) { validateRange(index); /********** Begin *********/ int oldVal=elements[index]; for (int i = index; i < size - 1; i++) { elements[i] = elements[i + 1]; } --size; return oldVal; /********** End *********/ } /** * 校验索引范围 * * @param index */ private void validateRange(int index) { if (index >= size || index < 0) { throw new ArrayIndexOutOfBoundsException("索引越界了哦!Index: " + index + ", Size: " + size); } } /** * 校验索引范围 * * @param index */ private void validateRangeForAdd(int index) { if (index > size || index < 0) throw new IndexOutOfBoundsException("索引越界了哦!Index: " + index + ", Size: " + size); } /** * 动态扩展数组大小 * * @param capacity */ private void resize(int capacity) { assert capacity > size; int[] tmp = new int[capacity]; for (int i = 0; i < size; i++) { tmp[i] = elements[i]; } elements = tmp; } }
顺序表的实现之查询功能package step2; /** * Created by zengpeng on 2017/12/25. */ public class MyArrayList { private int[] elements;//元素 private int size;//List中当前的元素个数 public MyArrayList() { this(1);//List默认大小为1 } /** * 按指定大小capacity构造List * * @param capacity List初始化时的大小 */ public MyArrayList(int capacity) { elements = new int[capacity]; size = 0; } /** * 返回List中元素的个数 * * @return */ public int size() { return size; } /** * 添加一个元素到末尾 * * @param item */ public void Add(int item) { int len = elements.length; if (size == len - 1) { resize(2 * len); } elements[size++] = item; } /** * 添加一个元素到指定位置index * * @param index * @param item */ public void Add(int index, int item) { validateRangeForAdd(index); int len = elements.length; if (size == len - 1) { resize(2 * len); } for (int i = size; i > index; i--) { elements[i] = elements[i - 1]; } elements[index] = item; size++; } /** * 删除指定位置index的元素,并返回被删除的元素 * * @param index * @return 被删除的元素 */ public int remove(int index) { validateRange(index); int oldVal = elements[index]; for (int i = index; i < size - 1; i++) { elements[i] = elements[i + 1]; } --size; return oldVal; } /** * 返回表中下标为index的元素 * @param index 下标 * @return */ public int get(int index) { validateRange(index); /********** Begin *********/ return elements[index]; /********** End *********/ } /** * 校验索引范围 * * @param index */ private void validateRange(int index) { if (index >= size || index < 0) { throw new ArrayIndexOutOfBoundsException("索引越界了哦!Index: " + index + ", Size: " + size); } } /** * 校验索引范围 * * @param index */ private void validateRangeForAdd(int index) { if (index > size || index < 0) throw new IndexOutOfBoundsException("索引越界了哦!Index: " + index + ", Size: " + size); } /** * 动态扩展数组大小 * * @param capacity */ private void resize(int capacity) { assert capacity > size; int[] tmp = new int[capacity]; for (int i = 0; i < size; i++) { tmp[i] = elements[i]; } elements = tmp; } }
单链表的实现之增删功能package step3; /** * Created by zengpeng on 2017/12/25. */ public class MyLinkedList { private Node first;//头结点,不存数据 private Node last;//指向链表的最后一个节点 private int size; public MyLinkedList() { size = 0; first = new Node(0, null); last = null; } /** * 添加到链表尾部 * * @param item */ public void add(int item) { /********** Begin *********/ final Node l = last; final Node node = new Node(item, null); last = node; if (first.next == null) {//首次添加 first.next = node; } else { l.next = node; } ++size; /********** End *********/ } /** * 添加数据item到指定位置index * index从0开始 * @param index * @param item */ public void add(int index, int item) { checkPosIndex(index); /********** Begin *********/ int n = index; Node l = first; while ((n--) > 0) { l = l.next; } final Node node = new Node(item, null); if (null == first.next) {//首次添加 last = node; } node.next = l.next; l.next = node; ++size; /********** End *********/ } /** * 删除指定位置index处的元素并返回, index从0开始 * @param index * @return */ public int remove(int index) { checkPosIndex(index); /********** Begin *********/ Node f = first; while ((index--) > 0) { f = f.next; } Node del = f.next; if (del == last) {//删除最后一个元素 last = f; } f.next = del.next; del.next = null; int oldVal = del.item; del = null; --size; return oldVal; /********** End *********/ } public int size() { return size; } private void checkPosIndex(int index) { if (index < 0 || index > size) { throw new IndexOutOfBoundsException("Index: " + index + ", Size: " + size); } } //结点内部类 private static class Node { int item; Node next; Node(int item, Node next) { this.item = item; this.next = next; } } }
单链表的实现之查询功能package step4; /** * Created by zengpeng on 2017/12/25. */ public class MyLinkedList { private Node first;//头结点,不存数据 private Node last;//指向链表的最后一个节点 private int size; public MyLinkedList() { size = 0; first = new Node(0, null); last = null; } /** * 添加到链表尾部 * * @param item */ public void add(int item) { final Node l = last; final Node node = new Node(item, null); last = node; if (first.next == null) {//首次添加 first.next = node; } else { l.next = node; } ++size; } /** * 添加数据item到指定位置index * index从0开始 * @param index * @param item */ public void add(int index, int item) { checkPosIndex(index); int n = index; Node l = first; while ((n--) > 0) { l = l.next; } final Node node = new Node(item, null); if (null == first.next) {//首次添加 last = node; } node.next = l.next; l.next = node; ++size; } /** * 删除指定位置index处的元素并返回, index从0开始 * @param index * @return */ public int remove(int index) { checkPosIndex(index); Node f = first; while ((index--) > 0) { f = f.next; } Node del = f.next; if (del == last) {//删除最后一个元素 last = f; } f.next = del.next; del.next = null; int oldVal = del.item; del = null; --size; return oldVal; } /** * 获取链表中第index个元素 * @param index * @return */ public int get(int index) { checkPosIndex(index); /********** Begin *********/ Node f = first.next; while ((index--) > 0) { f = f.next; } int val = f.item; return val; /********** End *********/ } public int size() { return size; } private void checkPosIndex(int index) { if (index < 0 || index > size) { throw new IndexOutOfBoundsException("Index: " + index + ", Size: " + size); } } //结点内部类 private static class Node { int item; Node next; Node(int item, Node next) { this.item = item; this.next = next; } } }
Java数据结构-循环链表的设计与实现
单循环链表的实现一链表的添加、遍历
package step1; /** * Created by sykus on 2018/1/15. */ public class MyCircleLinkedList { private Node head;//头结点, 不存数据 private Node tail;//尾结点, 指向链表的最后一个节点 private int size; public MyCircleLinkedList() { head = new Node(Integer.MIN_VALUE, null); head.next = head; tail = head; size = 0; } /** * 添加到链表尾部 * * @param item */ public void add(int item) { /********** Begin *********/ Node node = new Node(item, tail.next); tail.next = node; tail = node; ++size; /********** End *********/ } /** * 遍历链表并输出元素 */ public void output() { /********** Begin *********/ Node p = head; while (p.next != head) { p = p.next; System.out.println(p.item); } /********** End *********/ } public boolean isEmpty() { return head.next == head; } public int size() { return size; } //结点内部类 private static class Node { int item; Node next; Node(int item, Node next) { this.item = item; this.next = next; } } }
单循环链表的实现一链表的删除package step2; /** * Created by sykus on 2018/1/15. */ public class MyCircleLinkedList { private Node head;//头结点, 不存数据 private Node tail;//尾结点, 指向链表的最后一个节点 private int size; public MyCircleLinkedList() { head = new Node(Integer.MIN_VALUE, null); head.next = head; tail = head; size = 0; } /** * 添加到链表尾部 * * @param item */ public void add(int item) { Node node = new Node(item, tail.next); tail.next = node; tail = node; ++size; } /** * 遍历链表并输出元素 */ public void output() { Node p = head; while (p.next != head) { p = p.next; System.out.println(p.item); } } /** * 删除从头结点开始的第index个结点 * index从0开始 * * @param index * @return */ public int remove(int index) { checkPosIndex(index); /********** Begin *********/ Node f = head; while ((index--) > 0) { f = f.next; } Node del = f.next; if (del == tail) {//要删除的是尾结点 tail = f;//使tail依然指向末尾结点 } f.next = del.next; del.next = null; int oldVal = del.item; del = null; --size; return oldVal; /********** End *********/ } public boolean isEmpty() { return head.next == head; } public int size() { return size; } private void checkPosIndex(int index) { if (index < 0 || index >= size) { throw new IndexOutOfBoundsException("Index: " + index + ", Size: " + size); } } //结点内部类 private static class Node { int item; Node next; Node(int item, Node next) { this.item = item; this.next = next; } } }
双向循环链表的实现一链表的插入package step3; /** * Created by sykus on 2018/1/15. */ public class MyDoubleLinkedList { private Node head;//头结点 private Node tail;//指向链表的尾结点 private int size; public MyDoubleLinkedList() { head = new Node(null, Integer.MIN_VALUE, null); head.next = head.prev = head; tail = head; size = 0; } /** * 添加元素到表尾 * * @param item */ public void add(int item) { /********** Begin *********/ Node newNode = new Node(null, item, null); tail.next = newNode; newNode.prev = tail; newNode.next = head; head.prev = newNode; tail = newNode; ++size; /********** End *********/ } /** * 打印双向链表 * * @param flag true从左向右顺序打印, false从右向左顺序打印 */ public void printList(boolean flag) { Node f = head; if (flag) {//向右 while (f.next != head) { f = f.next; System.out.print(f.item + " "); } } else {//向左 while (f.prev != head) { f = f.prev; System.out.print(f.item + " "); } } } public int size() { return size; } //结点内部类 private static class Node { int item; Node next;//直接后继引用 Node prev;//直接前驱引用 Node(Node prev, int item, Node next) { this.prev = prev; this.item = item; this.next = next; } } }
双向循环链表的实现一链表的删除package step4; /** * Created by sykus on 2018/1/15. */ public class MyDoubleLinkedList { private Node head;//头结点 private Node tail;//指向链表的尾结点 private int size; public MyDoubleLinkedList() { head = new Node(null, Integer.MIN_VALUE, null); head.next = head.prev = head; tail = head; size = 0; } /** * 添加元素到表尾 * * @param item */ public void add(int item) { Node newNode = new Node(null, item, null); tail.next = newNode; newNode.prev = tail; newNode.next = head; head.prev = newNode; tail = newNode; ++size; } /** * 删除指定位置index出的结点,并返回其值 * * @param index * @return */ public int remove(int index) { checkPosIndex(index);// /********** Begin *********/ Node p = head.next; while ((index--) > 0) { p = p.next; } if (p == tail) { tail = p.prev; } p.prev.next = p.next; p.next.prev = p.prev; int val = p.item; p = null; --size; return val; /********** End *********/ } /** * 打印双向链表 * * @param flag true从左向右顺序打印, false从右向左顺序打印 */ public void printList(boolean flag) { Node f = head; if (flag) {//向右 while (f.next != head) { f = f.next; System.out.print(f.item + " "); } } else {//向左 while (f.prev != head) { f = f.prev; System.out.print(f.item + " "); } } } public int size() { return size; } private void checkPosIndex(int index) { if (index < 0 || index >= size) { throw new IndexOutOfBoundsException("Index: " + index + ", Size: " + size); } } //结点内部类 private static class Node { int item; Node next;//直接后继引用 Node prev;//直接前驱引用 Node(Node prev, int item, Node next) { this.prev = prev; this.item = item; this.next = next; } } }
Java 数据结构之二叉树
二又树的实现之前序遍历
package step1; /** * Created by zengpeng on 2018/2/9. */ public class BinaryTree { private TreeNode root;//根节点 public BinaryTree() { root = null; } public void preOrder(TreeNode root) { /********** Begin *********/ if (root == null) { return; } System.out.println(root.item); preOrder(root.leftChild); preOrder(root.rightChild); /********** End *********/ } /** * 以数组arr从左至右构建二叉树 * * @param arr * @param n * @return */ public TreeNode createTree(int arr[]) { TreeNode tmp[] = new TreeNode[arr.length + 1]; for (int k = 1; k <= arr.length; k++) { TreeNode node = new TreeNode(arr[k - 1]); tmp[k] = node; if (k == 1) { root = node; } else { int j = k / 2; if (k % 2 == 0) { tmp[j].leftChild = node; } else { tmp[j].rightChild = node; } } } return root; } public static class TreeNode { private TreeNode leftChild; private TreeNode rightChild; private int item; public TreeNode(int item) { this(null, null, item); } public TreeNode(TreeNode leftChild, TreeNode rightChild, int item) { this.leftChild = leftChild; this.rightChild = rightChild; this.item = item; } } }
二又树的实现之中序遍历package step2; /** * Created by zengpeng on 2018/2/12. */ public class BinaryTree { private TreeNode root;//根节点 public BinaryTree() { root = null; } public void inOrder(TreeNode root) { /********** Begin *********/ if (root == null) { return; } inOrder(root.leftChild); System.out.println(root.item); inOrder(root.rightChild); /********** End *********/ } /** * 根据二叉树的性质,以数组arr从左至右构建一颗满二叉树 * * @param arr * @param n * @return */ public TreeNode createTree(int arr[]) { TreeNode tmp[] = new TreeNode[arr.length + 1]; for (int k = 1; k <= arr.length; k++) { TreeNode node = new TreeNode(arr[k - 1]); tmp[k] = node; if (k == 1) { root = node; } else { int j = k / 2; if (k % 2 == 0) { tmp[j].leftChild = node; } else { tmp[j].rightChild = node; } } } return root; } public static class TreeNode { private TreeNode leftChild; private TreeNode rightChild; private int item; public TreeNode(int item) { this(null, null, item); } public TreeNode(TreeNode leftChild, TreeNode rightChild, int item) { this.leftChild = leftChild; this.rightChild = rightChild; this.item = item; } } }
二又树的实现之后序遍历package step3; /** * Created by zengpeng on 2018/2/12. */ public class BinaryTree { private TreeNode root;//根节点 public BinaryTree() { root = null; } public void postOrder(TreeNode root) { /********** Begin *********/ if (root == null) { return; } postOrder(root.leftChild); postOrder(root.rightChild); System.out.println(root.item); /********** End *********/ } /** * 根据二叉树的性质,以数组arr从左至右构建一颗满二叉树 * * @param arr * @param n * @return */ public TreeNode createTree(int arr[]) { TreeNode tmp[] = new TreeNode[arr.length + 1]; for (int k = 1; k <= arr.length; k++) { TreeNode node = new TreeNode(arr[k - 1]); tmp[k] = node; if (k == 1) { root = node; } else { int j = k / 2; if (k % 2 == 0) { tmp[j].leftChild = node; } else { tmp[j].rightChild = node; } } } return root; } public static class TreeNode { private TreeNode leftChild; private TreeNode rightChild; private int item; public TreeNode(int item) { this(null, null, item); } public TreeNode(TreeNode leftChild, TreeNode rightChild, int item) { this.leftChild = leftChild; this.rightChild = rightChild; this.item = item; } } }
Java 数据结构之二叉搜索树
二叉搜索树的介绍与构建
package step1; /** * Created by zengpeng on 2018/3/3. */ public class BSTree { private TreeNode root;//根结点 public BSTree() { root = null; } /** * 向树root中插入key * * @param key 要插入的值 */ public void insert(int key) { /********** Begin *********/ TreeNode x = root; TreeNode p = null;//始终指向x的父结点 while (x != null) { p = x; if (key < x.item) { x = x.leftChild; } else { x = x.rightChild; } } if (null == p) {//空树 root = new TreeNode(key); } else if (key < p.item) { p.leftChild = new TreeNode(key); } else { p.rightChild = new TreeNode(key); } /********** End *********/ } /** * 前序遍历 */ public void preOrder() { preOrder(root); } /** * 中序遍历 */ public void inOrder() { inOrder(root); } /** * 后序遍历 */ public void postOrder(){ postOrder(root); } private void preOrder(TreeNode node) { if (node != null) { System.out.print(node.item + " "); preOrder(node.leftChild); preOrder(node.rightChild); } } private void inOrder(TreeNode node) { if (node != null) { inOrder(node.leftChild); System.out.print(node.item + " "); inOrder(node.rightChild); } } private void postOrder(TreeNode node) { if (node != null) { postOrder(node.leftChild); postOrder(node.rightChild); System.out.print(node.item + " "); } } public static class TreeNode { private TreeNode leftChild; private TreeNode rightChild; private int item; public TreeNode(int item) { this(null, null, item); } public TreeNode(TreeNode leftChild, TreeNode rightChild, int item) { this.leftChild = leftChild; this.rightChild = rightChild; this.item = item; } } }
二又搜索树的删除package step2; /** * Created by zengpeng on 2018/3/14. */ public class BSTree { private TreeNode root;//根结点 public BSTree() { root = null; } /** * 向树root中插入a * * @param key 要插入的值 */ public void insert(int key) { TreeNode x = root; TreeNode p = null;//始终指向x的父结点 while (x != null) { p = x; if (key < x.item) { x = x.leftChild; } else { x = x.rightChild; } } if (null == p) {//空树 root = new TreeNode(key); } else if (key < p.item) { p.leftChild = new TreeNode(key); } else { p.rightChild = new TreeNode(key); } } /** * 在树root中删除结点key * * @param key * @return */ public void delete(int key) { root = delete(root, key); } private TreeNode delete(TreeNode x, int key) { /********** Begin *********/ if (x == null) { return null; } if (key < x.item) { x.leftChild = delete(x.leftChild, key); } else if (key > x.item) { x.rightChild = delete(x.rightChild, key); } else { if (x.leftChild == null) return x.rightChild; if (x.rightChild == null) return x.leftChild; TreeNode t = x; x = min(t.rightChild); x.rightChild = deleteMin(t.rightChild); x.leftChild = t.leftChild; } return x; /********** End *********/ } /** * 删除树x中的最小结点 * * @param x * @return */ private TreeNode deleteMin(TreeNode x) { if (x.leftChild == null) return x.rightChild; x.leftChild = deleteMin(x.leftChild); return x; } /** * 查找树x中的最小结点 * * @param x * @return */ private TreeNode min(TreeNode x) { TreeNode p = x; while (p.leftChild != null) { p = p.leftChild; } return p; } public void preOrder() { preOrder(root); } private void preOrder(TreeNode node) { if (node != null) { System.out.print(node.item + " "); preOrder(node.leftChild); preOrder(node.rightChild); } } public void inOrder() { inOrder(root); } private void inOrder(TreeNode node) { if (node != null) { inOrder(node.leftChild); System.out.print(node.item + " "); inOrder(node.rightChild); } } public void postOrder() { postOrder(root); } private void postOrder(TreeNode node) { if (node != null) { postOrder(node.leftChild); postOrder(node.rightChild); System.out.print(node.item + " "); } } public static class TreeNode { private TreeNode leftChild; private TreeNode rightChild; private int item; public TreeNode(int item) { this(null, null, item); } public TreeNode(TreeNode leftChild, TreeNode rightChild, int item) { this.leftChild = leftChild; this.rightChild = rightChild; this.item = item; } } }
二又搜索树的查找package step3; /** * Created by zengpeng on 2018/3/14. */ public class BSTree { private TreeNode root;//根结点 public BSTree() { root = null; } /** * 向树root中插入a * * @param key 要插入的值 */ public void insert(int key) { TreeNode x = root; TreeNode p = null;//始终指向x的父结点 while (x != null) { p = x; if (key < x.item) { x = x.leftChild; } else { x = x.rightChild; } } if (null == p) {//空树 root = new TreeNode(key); } else if (key < p.item) { p.leftChild = new TreeNode(key); } else { p.rightChild = new TreeNode(key); } } /** * 判断树root中是否包含key,包含则返回true,不包含返回false * * @param key * @return */ public boolean search(int key) { /********** Begin *********/ TreeNode p = root; while (p != null && key != p.item) { if (key < p.item) { p = p.leftChild; } else { p = p.rightChild; } } if (p == null) { return false; } else { return true; } /********** End *********/ } /** * 在树root中删除结点key * * @param key * @return */ public void delete(int key) { root = delete(root, key); } private TreeNode delete(TreeNode x, int key) { if (x == null) { return null; } if (key < x.item) { x.leftChild = delete(x.leftChild, key); } else if (key > x.item) { x.rightChild = delete(x.rightChild, key); } else { if (x.leftChild == null) return x.rightChild; if (x.rightChild == null) return x.leftChild; TreeNode t = x; x = min(t.rightChild); x.rightChild = deleteMin(t.rightChild); x.leftChild = t.leftChild; } return x; } /** * 删除树x中的最小结点 * @param x * @return */ private TreeNode deleteMin(TreeNode x) { if (x.leftChild == null) return x.rightChild; x.leftChild = deleteMin(x.leftChild); return x; } /** * 查找树x中的最小结点 * * @param x * @return */ private TreeNode min(TreeNode x) { TreeNode p = x; while (p.leftChild != null) { p = p.leftChild; } return p; } public void preOrder() { preOrder(root); } public void inOrder() { inOrder(root); } public void postOrder() { postOrder(root); } private void preOrder(TreeNode node) { if (node != null) { System.out.print(node.item + " "); preOrder(node.leftChild); preOrder(node.rightChild); } } private void inOrder(TreeNode node) { if (node != null) { inOrder(node.leftChild); System.out.print(node.item + " "); inOrder(node.rightChild); } } private void postOrder(TreeNode node) { if (node != null) { postOrder(node.leftChild); postOrder(node.rightChild); System.out.print(node.item + " "); } } public static class TreeNode { private TreeNode leftChild; private TreeNode rightChild; private int item; public TreeNode(int item) { this(null, null, item); } public TreeNode(TreeNode leftChild, TreeNode rightChild, int item) { this.leftChild = leftChild; this.rightChild = rightChild; this.item = item; } } }
Java 数据结构之图
图的表示
package step1; import java.util.ArrayList; public class Graph { private int V;//顶点数 private int E;//边数 private ArrayList<Integer>[] adj;//邻接表 public Graph(int v) { if (v < 0) throw new IllegalArgumentException("Number of vertices must be nonnegative"); V = v; E = 0; adj = new ArrayList[V + 1]; for (int i = 0; i <= this.V; i++) { adj[i] = new ArrayList<Integer>(); } } public void addEdge(int v, int w) { /********** Begin *********/ adj[v].add(w); adj[w].add(v); E++; /********** End *********/ } public String toString() { StringBuilder s = new StringBuilder(); s.append(V + " 个顶点, " + E + " 条边\n"); for (int v = 1; v <= V; v++) { s.append(v + ": "); for (int w : adj[v]) { s.append(w + " "); } s.append("\n"); } return s.toString(); } }
深度优先搜索package step2; import java.util.ArrayList; public class DFSGraph { private boolean[] marked; private int V;//顶点数 private int E;//边数 private ArrayList<Integer>[] adj;//邻接表 public DFSGraph(int v) { if (v < 0) throw new IllegalArgumentException("Number of vertices must be nonnegative"); V = v; E = 0; adj = new ArrayList[V + 1]; marked = new boolean[V + 1]; for (int i = 0; i <= this.V; i++) { adj[i] = new ArrayList<Integer>(); } } public void addEdge(int v, int w) { adj[v].add(w); adj[w].add(v); E++; } public void DFS(int v) { /********** Begin *********/ marked[v] = true; System.out.print(v + " "); for (int w : adj[v]) { if (!marked[w]) { DFS(w); } } /********** End *********/ } public String toString() { StringBuilder s = new StringBuilder(); s.append(V + " 个顶点, " + E + " 条边\n"); for (int v = 1; v <= V; v++) { s.append(v + ": "); for (int w : adj[v]) { s.append(w + " "); } s.append("\n"); } return s.toString(); } }
广度优先搜索package step3; import java.util.ArrayList; import java.util.LinkedList; import java.util.Queue; public class BFSGraph { private int V;//顶点数 private int E;//边数 private boolean[] marked; private ArrayList<Integer>[] adj;//邻接表 public BFSGraph(int v) { if (v < 0) throw new IllegalArgumentException("Number of vertices must be nonnegative"); V = v; E = 0; adj = new ArrayList[V + 1]; marked = new boolean[V + 1]; for (int i = 0; i <= this.V; i++) { adj[i] = new ArrayList<Integer>(); } } public void addEdge(int v, int w) { adj[v].add(w); adj[w].add(v); E++; } public void BFS(int s) { /********** Begin *********/ Queue<Integer> que = new LinkedList<>(); que.offer(s); marked[s] = true; while (!que.isEmpty()) { int v = que.poll(); System.out.print(v + " "); for (int w : adj[v]) { if (!marked[w]) { que.offer(w); marked[w] = true; } } } /********** End *********/ } public String toString() { StringBuilder s = new StringBuilder(); s.append(V + " 个顶点, " + E + " 条边\n"); for (int v = 1; v <= V; v++) { s.append(v + ": "); for (int w : adj[v]) { s.append(w + " "); } s.append("\n"); } return s.toString(); } }
单源最短路径package step4; import java.util.*; public class ShortestPath { private int V;//顶点数 private int E;//边数 private int[] dist; private ArrayList<Integer>[] adj;//邻接表 private int[][] weight;//权重 public ShortestPath(int v, int e) { V = v; E = e; dist = new int[V + 1]; adj = new ArrayList[V + 1]; weight = new int[V + 1][V + 1]; for (int i = 0; i <= this.V; i++) { adj[i] = new ArrayList<Integer>(); } } public void addEdge(int u, int v, int w) { adj[u].add(v); adj[v].add(u); weight[u][v] = weight[v][u] = w; } public int[] Paths(int source) { /********** Begin *********/ Queue<Integer> Q = new LinkedList<Integer>(); dist[source] = 0; for (int i = 1; i <= V; i++) { if (i != source) { dist[i] = Integer.MAX_VALUE; } Q.offer(i); } while (!Q.isEmpty()) { int minV = Integer.MAX_VALUE; int v = source; for (int i = 0; i < Q.size(); i++) { int index = ((LinkedList<Integer>) Q).get(i); if (dist[index] < minV) { minV = dist[index]; v = index; } } Q.poll(); Q.remove(v); for (int u : adj[v]) { int alt = dist[v] + weight[v][u]; if (alt < dist[u]) { dist[u] = alt; } } } return dist; /********** End *********/ } /** * 打印源点到所有顶点的距离,INF为无穷大 * * @param dist */ public void print(int[] dist) { for (int i = 1; i <= V; i++) { if (dist[i] == Integer.MAX_VALUE) { System.out.print("INF "); } else { System.out.print(dist[i] + " "); } } } }
Java 数据结构之排序
选择排序
package step1; /** * Created by sykus on 2018/3/20. */ public class SelectionSort { /** * 选择排序 * * @param arr */ public static void sort(int arr[]) { /********** Begin *********/ for (int i = 0; i < arr.length-1; i++) { for (int j = i + 1; j < arr.length; j++) { if (arr[j] < arr[i]) { int tmp = arr[i]; arr[i] = arr[j]; arr[j] = tmp; } } print(arr); } /********** End *********/ } private static void print(int arr[]) { for (int i = 0; i < arr.length; i++) { System.out.print(arr[i] + " "); } System.out.println(); } }
插入排序package step2; /** * Created by sykus on 2018/3/20. */ public class InsertionSort { public static void sort(int arr[]) { /********** Begin *********/ for (int i = 1; i < arr.length; i++) { int j = i; int tmp = arr[j]; while (j > 0 && tmp < arr[j - 1]) { arr[j] = arr[j - 1]; j--; } arr[j] = tmp; print(arr); } /********** End *********/ } private static void print(int arr[]) { for (int i = 0; i < arr.length; i++) { System.out.print(arr[i] + " "); } System.out.println(); } }
归并排序package step3; /** * Created by sykus on 2018/3/20. */ public class MergeSort { /** * lo, hi都是指下标 */ public static void sort(int arr[], int lo, int hi) { if (lo < hi) { int mid = (lo + hi) / 2; sort(arr, lo, mid); sort(arr, mid + 1, hi); merge(arr, lo, mid, hi); print(arr); } } private static void merge(int arr[], int p, int q, int r) { /********** Begin *********/ int n1 = q - p + 1; int n2 = r - q; int L[] = new int[n1 + 1]; int R[] = new int[n2 + 1]; for (int i = 0; i < n1; i++) { L[i] = arr[p + i]; } for (int j = 0; j < n2; j++) { R[j] = arr[q + j + 1]; } L[n1] = Integer.MAX_VALUE; R[n2] = Integer.MAX_VALUE; int i = 0, j = 0; for (int k = p; k <= r; k++) { if (L[i] <= R[j]) { arr[k] = L[i]; i++; } else { arr[k] = R[j]; j++; } } /********** End *********/ } private static void print(int arr[]) { for (int i = 0; i < arr.length; i++) { System.out.print(arr[i] + " "); } System.out.println(); } }
快速排序package step4; /** * Created by sykus on 2018/3/20. */ public class QuickSort { public void sort(int arr[], int low, int high) { /********** Begin *********/ int i = low; int j = high + 1; int povit = arr[low]; while (i < j) { while (j > low && arr[--j] >= povit) ; while (i < high && arr[++i] <= povit) ; if (i>=j)break; int temp = arr[j]; arr[j] = arr[i]; arr[i] = temp; print(arr); } int temp = arr[j]; arr[j] = arr[low]; arr[low] = temp; print(arr); if (i > low) sort(arr, low, j - 1); if (j < high) sort(arr, j + 1, high); /********** End *********/ } private static void print(int arr[]) { for (int i = 0; i < arr.length; i++) { System.out.print(arr[i] + " "); } System.out.println(); } }
堆排序package step5; /** * Created by sykus on 2018/3/20. */ public class HeapSort { public static void sort(int arr[]) { /********** Begin *********/ int n = arr.length; for (int k = n / 2; k >= 1; k--) { int l = k; while (2 * l <= n) { int j = 2 * l; if (j < n && arr[j - 1] < arr[j + 1 - 1]) j++; if (arr[l - 1] > arr[j - 1]) break; int tmp = arr[l - 1]; arr[l - 1] = arr[j - 1]; arr[j - 1] = tmp; l = j; } } while (n > 1) { int tmp = arr[0]; arr[0] = arr[n - 1]; arr[n - 1] = tmp; int k = 1; n--; while (2 * k <= n) { int j = 2 * k; if (j < n && arr[j - 1] < arr[j]) j++; if (arr[k - 1] > arr[j - 1]) break; tmp = arr[k - 1]; arr[k - 1] = arr[j - 1]; arr[j - 1] = tmp; k = j; } print(arr); } /********** End *********/ } private static void print(int[] arr) { for (int i = 0; i < arr.length; i++) { System.out.print(arr[i] + " "); } System.out.println(); } }