数据结构

72 阅读3分钟

栈、队列、链表、二叉树、红黑树、散列表和位图。

优点:顶部元素插入和取出快
缺点:其他元素的操作慢
核心方法:pop()push()peek()
栈的具体实现过程:

//定义栈的数据结构
package hello.java.datastructure;
public class Stack<E> {
    private Object[] data = null;
    private int maxSize = 0//栈的容量
    private int top = -1;
    Stack() {
        this(10); //默认栈大小为10
    }
    Stack(int initialSize) {
        if(initialSize >= 0) {
            this.maxSize = initialSize;
            data = new Object[initialSize];
            top = -1;
        } else {
            throw new RuntimeException("初始化大小不能小于0: " + initialSize);
        }
    }
}

public boolean push(E e) {
    if(top == maxSize - 1) {
        throw new RuntimeException("栈已满,无法入栈!");
    } else {
        data[top++] = e;
        return true;
    }
}

public E pop() {
    if(top == -1) {
        throw new RuntimeException("栈为空!");
    } else {
        return (E)data[top--];
    }
}

public E peek() {
    if(top == -1) {
        throw new RuntimeException("栈为空!");
    } else {
        return (E)data[top];
    }
}

队列

优点:顶部元素插入和尾部元素取出快
缺点:存取其他元素慢
核心方法:add()poll()peek()
队列的具体实现过程:

packate hello.java.datastructure;
public class Queue<E> {
    private Object[] data = null;
    private int maxSize;
    private int front;
    private int rear;

    public Queue(int initialSize) {
        this(10);
    }
    public Queue(int initialSize) {
        if(initialSize >= 0) {
            this.maxSize = initialSize;
            data = new Object[initialSize];
            front = rear = 0;
        } else {
            throw new RuntimeException("初始化大小不能小于0:" + initialSize);
        }
    }
}

public boolean add(E e) {
    if(rear == maxSize) {
        throw new RuntimeException("队列已满,无法入队!");
    } else {
        data[rear++] = e;
        return true;
    }
}

public E poll() {
    if(empty()) {
        throw new RuntimeException("空队列异常!");
    } else {
        E value = (E) data[front];
        data[front++] = null;
        return value;
    }
}

public E peek() {
    if(empty()) {
        throw new RuntimeException("空队列异常!");
    } else {
        return (E) data[front];
    }
}

链表

优点:插入、删除速度快
缺点:查找慢
单向链表:查找、插入、删除 双向链表:头部尾部增加节点、删除节点
具体实现如下:

//单向链表
public class SingleLinkedList {
    private int length;
    private Node head;
    public SingleLinkedList() {
        size = 0;
        head = null;
    }
    private class Node{
        private Object data;
        private Node next;
        public Node(Object data) {
            this.data = data;
        }
    }
}

public Object addHead(Object obj) {
    Node newHead = new Node(obj);
    if(length == 0) {
        head = newHead;
    } else {
        newHead.next = head;
        head = newHead;
    }
    length ++;
    return obj;
}

public boolean delete(Object value) {
    if(length == 0) {
        return false;
    }
    Node current = head;
    Node previous = head;
    while(current.data != value) {
        if(current.next == null) {
            return false;
        } else {
            previous = current;
            current = current.next;
        }
    }
    if(current == head) {
        head = current.next;
        length--;
    } else {
        previous.next = current.next;
        length --;
    }
    return true;
}

public Node find(Object obj) {
    Node current = head;
    int tempSize = length;
    while(tempSize > 0) {
        if(obj.equals(current.data)){
            return current;
        } else {
            current = current.next;
        }
        tempSize --;
    }
    return null;
}
//双向链表
public class TwoWayLinkedList {
    private Node head;
    private Node tail;
    private int length;
    private class Node {
        private Object data;
        private Node next;
        private Node prev;
        public Node(Object data) {
            this.data = data;
        }
    }
    public TwoWayLinkedList() {
        size = 0;
        head = null;
        tail = null;
    }
}
public void addHead(Object value) {
    Node newNode = new Node(value);
    if(length == 0){
        head = newHead;
        tail = newHead;
        length ++;
    } else {
        head.prev = newNode;
        newNode.next = head;
        head = newNode;
        length ++;
    }
}
public void addTail(Object value) {
    Node newNode = new Node(value);
    if(length == 0) {
        head = newNode;
        tail = newNode;
        length ++;
    } else {
        newNode.prev = tail;
        tail.next = newNode;
        tail = newNode;
        length ++;
    }
}
public Node deleteHead() {
    Node temp = head;
    if(length != 0) {
        head = head.next;
        head.prev = null;
        length --;
        return temp;
    }
}
public Node deleteTail() {
    Node temp = tail;
    if(length != 0) {
        tail = tail.prev;
        tail.next = null;
        length --;
        return temp;
    } else {
        return null;
    }
}

二叉树

优点:插入、删除和查找速度快
缺点:删除算法复杂 具体实现:

public class Node {
    private int value;
    private Node left;
    private Node right;
    public Node() {

    }
    public Node(Node left, Node right, int value) {
        this.left = left;
        this.right = right;
        this.value = value;
    }
    public Node(int value) {
        this(null, null, value);
    }
    public Node getLeft() {
        return this.left;
    }
    public void setLeft() {
        this.left = left;
    }
    public Node getRight() {
        return this.right;
    }
    public void setRight() {
        this.right = right;
    }
    public Node getValue() {
        return this.value;
    }
    public void setValue() {
        this.value = value;
    }
}
public void insertBST(int key) {
    Node p = root;
    Node prev = null;
    while(p != null) {
        prev = p;
        if(key < p.getValue()) p = p.getLeft();
        else if (key > p.getValue()) p = p.getRight();
        else return;
    }
    if(root == null)
        root = new Node(key);
    else if (key < prev.getValue()) prev.setLeft(new Node(key));
    else prev.setRight(new Node(key));
}
public void deleteBST(int key) {
    deleteBST(root, key);
}
private boolean deleteBST(Node node, int key) {
    if(node == null) return false;
    else {
        if(key == node.getValue()) {
            return delete(node);
        } else if {
            return deleteBST(node.getLeft(), key);
        } else {
            return deleteBST(node.getRight(), key);
        }
    }
}
private boolean delete(Node node) {
    Node temp = null;
    if(node.getRight() == null) {
        temp = node;
        node = node.getLeft();
    } else if(node.getLeft() == null) {
        temp = node;
        node = node.getRight();
    } else {
        temp = node;
        Node s = node;
        s = s.getLeft();
        while(s.getRight != null) {
            temp = s;
            s = s.getRight();
        }
        node.setValue(s.getValue());
        if(temp != node) {
            temp.setRight(s.getLeft());
        } else {
            temp.setLeft(s.getLeft());
        }
    }
    return true;
}
public boolean searchBST(int key) {
    Node current = root;
    while(current != null) {
        if(key == current.getValue()) return true;
        else if (key < current.getValue()) current = current.getLeft();
        else current = current.getRight();
    }
    return false
}

二叉树的遍历实现如下:

递归版

public void PreOrder(Node T) {
    if(T != null) {
        visit(T);
        PreOrder(T.getLeft());
        PreOrder(T.getRight());
    }
}
public void InOrder(Node T) {
    if(T != null) {
        PreOrder(T.getLeft());
        visit(T);
        PreOrder(T.getRight());
    }
}
public void PostOrder(Node T) {
    if(T != null) {
        PreOrder(T.getLeft());
        PreOrder(T.getRight());
        visit(T);
    }
}

非递归版

public void PreOrder1(Node T) {
    InitStack(S);
    Node p = T;
    while(p||IsEmpty(S)){
        if(p) {
            visit(p);
            push(S,p);
            p = p.getLeft();
        } else {
            Pop(S,p);
            p = p.getRight();
        }
    }
}
public void InOrder1(Node T) {
    InitStack(S);
    Node p = T;
    while(p || !IsEmpty(S)) {
        if(p) {
            push(S, p);
            p = p.getLeft();
        } else {
            Pop(S,p);
            visit(p);
            P = p.getRight();
        }
    }
}
public void PostOrder1(Node T) {
    InitStack(S);
    Node p = T;
    Node r;
    while(p || !IsEmpty(S)) {
        if(p) {
            push(S,p);
            p = p.getLeft();
        } else {
            peek(S,p);
            if(p.getRight() != null && p.getRight() != r) {
                p = p.getRight();
                push(S,p);
                p = p.getLeft();
            } else {
                pop(S,p);
                visit(p);
                r = p;
                p = Null;
            }
        }
    }
}

层次遍历

public void LevelOrder(Node T) {
    InitQueue(Q);
    Node p;
    EnQueue(Q, T);
    while(!IsEmpty(Q)) {
        DeQueue(Q, p);
        visit(p);
        if(p.getLeft() != null) Enqueue(Q, p.getLeft());
        if(p.getRight() != null) Enqueue(Q, p.getRight());
    }
}

红黑树

优点:插入、删除和查找速度快
缺点:算法复杂

散列表

优点:插入、删除和查找速度快
缺点:数据散列,对存储空间浪费
具体实现:

public int hashCode() {
    int h = hash;
    if(h == 0 && value.length > 0) {
        char val[] = value;
        for (int i = 0; i < value.length; i++) {
            h = 31 * h + val[i];
        }
        hash = h;
    }
    return h;
}

位图

优点:节省存储空间
缺点:不方便描述复杂的数据关系
具体实现:

public class Bitmap {
    private byte[] bytes;
    private int length;
    public Bitmap(int length) {
        this.length = length;
        bytes = new byte[length % 8 == 0 ? length / 8 : length / 8 + 1];
    }
}

public boolean get(int index) {
    int i = index & 7;//得到目标bit在该Byte中的位置
    //取得Byte              高位置零              右移i位得到值
    if((bytes[index >> 3] & (01111111 >>> (7 - i))) >> i == 0) return false;
    else return true;
}

public void set(int index, boolean value) {
    if(value) bytes[index >> 3] |= 1 << (index & 7);//数据存在
    else bytes[index >> 3] &= ~(1 << (index & 7));//数据不存在
}