栈(后进先出LIFO)
import java.util.ArrayList;
import java.util.List;
public class Stack<T> {
private List<T> list;
public Stack(){
list = new ArrayList<T>();
}
public void push(T element){
list.add(0,element);
}
public T pop(){
if(list.size()==0)
return null;
return list.remove(0);
}
public static void main(String[] args) {
Stack<Integer> stack = new Stack<>();
System.out.println(stack.pop());
stack.push(1);
stack.push(2);
System.out.println(stack.pop());
}
}
队列(先进先出FIFO)
import java.util.ArrayList;
import java.util.List;
public class Queue<T> {
private List<T> list;
public Queue(){
list = new ArrayList<T>();
}
public void push(T element){
list.add(element);
}
public T pop(){
if(list.size()==0)
return null;
return list.remove(0);
}
public static void main(String[] args) {
Queue<Integer> queue = new Queue<>();
System.out.println(queue.pop());
queue.push(1);
queue.push(2);
System.out.println(queue.pop());
System.out.println(queue.pop());
}
}
数组实现的链式结构
多数组key[x]、prev[x]、next[x]组成一个节点。
0 | 1 | 2 | 3 | 4 | 5 | |
key | A | E | C | B | D | F |
prev | -1 | 4 | 3 | 0 | 2 | 1 |
next | 3 | 5 | 4 | 2 | 1 | -2 |
单数组,通过偏移量记录每个节点的属性a[x]代表key,a[x+1]代表前一节点key对应数组下标,a[x+2]代表后一节点key对应数组下标
0 | 3 | 6 | 9 | 12 | 15 | ||||||||||||
A | -1 | 9 | E | 12 | 15 | C | 9 | 12 | B | 0 | 6 | D | 6 | 3 | F | 3 | -2 |
二叉树操作
import java.util.ArrayList;
public class BinaryTree {
class Node{
Node father = null;
Node left = null;
Node right = null;
Integer value;
private Node(){}
private Node(Integer value){this.value = value;}
}
private Node root;
private Integer size;
public BinaryTree(){
size = 0;
root = null;
}
//树中添加节点
public void add(Integer value){
if(size==0){
root = new Node(value);
size++;
return;
}
size++;
Node current = root;
Node newNode = new Node(value);
while(current != null){
if(current.value > value){
if(current.left == null){
current.left = newNode;
newNode.father = current;
return;
}else
current = current.left;
}else {
if(current.right == null){
current.right = newNode;
newNode.father = current;
return;
}else
current = current.right;
}
}
}
public String toString(){
if(size==0)
return null;
return inorderTreeWalk(root).toString();
}
//中序遍历二叉树,时间复杂度O(n),n为节点数
private ArrayList<Integer> inorderTreeWalk(Node node){
if(node != null) {
ArrayList left = inorderTreeWalk(node.left);
left.add(node.value);
ArrayList right = inorderTreeWalk(node.right);
left.addAll(right);
return left;
}else
return new ArrayList<>();
}
//根据key迭代查找节点,时间复杂度O(h),h为树的高度
public Node iterativeTreeSearch(Node x,Integer key){
while(x!=null && key != x.value){
if(key < x.value)
x = x.left;
else
x = x.right;
}
return x;
}
//获取最小节点,时间复杂度O(h),h为树的高度
public Node minimum(Node x){
while(x.left != null)
x = x.left;
return x;
}
//获取树的最大节点,时间复杂度O(h),h为树的高度
public Node maximum(Node x){
while(x.right != null)
x = x.right;
return x;
}
//获取根节点
public Node getRoot() {
return root;
}
//获取大小
public Integer getSize() {
return size;
}
/*节点上移
移除节点u,节点v上移
*/
private void transplant(Node u,Node v){
if(u.father == null)
root = v;
else if(u==u.father.left)
u.father.left = v;
else
u.father.right = v;
if(v!=null)
v.father = u.father;
}
//删除节点,时间复杂度O(h),h为树的高度
public void delete(Node z){
if(z.left==null) //无左孩子(包含无孩子),右孩子上移
transplant(z,z.right);
else if(z.right==null) //无有孩子
transplant(z,z.left); //左孩子上移
else{//有两个孩子
//取右孩子树的最小值,最小值没有左孩子,将最小节点提到原先z的位置
Node y = minimum(z.right);
if(y.father!=z){
transplant(y,y.right);// 最小节点提取出后右孩子树上移
y.right = z.right; //y成为右子树中第一个节点,且没有左孩子
y.right.father = y;
}
transplant(z,y); //移除z,y上移
y.left = z.left; //原z的左孩子,变为y的左孩子
y.left.father = y;
}
}
public static void main(String[] args) {
BinaryTree binaryTree = new BinaryTree();
binaryTree.add(5);
binaryTree.add(4);
binaryTree.add(6);
binaryTree.add(2);
binaryTree.add(7);
binaryTree.add(5);
System.out.println(binaryTree); //[2, 4, 5, 5, 6, 7]
System.out.println(binaryTree.minimum(binaryTree.getRoot()).value); //2
System.out.println(binaryTree.maximum(binaryTree.getRoot()).value); //7
binaryTree.delete(binaryTree.iterativeTreeSearch(binaryTree.getRoot(), 6));
System.out.println(binaryTree); //[2, 4, 5, 5, 7]
}
}