数据结构-基础

数据结构的组成

数据结构

对于每种结构的特点及优缺点的那个列表 即使记住了也是非常容易忘的 不如了解功能实现 需要时在分析优缺点

逻辑结构:

线性结构 -> 集合(无逻辑关系  只是放一块)
     线性结构(线性表 一对一):队列  栈  一维数组 给予特定特点 方便实现特定功能
非线性结构
      树(一对多)
      图(多对多)
      二位数组

内存结构:

顺序存储: 连续内存存储
链表存储:额外需要存储附近节点的引用
索引存储:额外需要存储索引表,索引表的存储又可以分树/哈希之类
散列存储:额外需要哈希算法

从面向对象的角度,其实是不关系内存结构的,所以虽然一种逻辑结构可以有多种内存表示,比如顺序表/链表 就是线性表+顺序存储/链表存储组成的,但我们常说的数据结构还是指的是逻辑结构

 package dataStructure;


import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;

/**
 * 参照linkedlist 
 * 链表  链式存储-- 查找取下标也是需要遍历  删除和新增和方便  可查看LinkedList双向链表
 *   维护头结点和链表大小  一直往下next
 * 哨兵 即守门的  在头和尾加哨兵 则能减少空值判断 则整体对外没有什么区别
 * head.pre = 哨兵
 * last.next = 哨兵
 *
 * Created by EX on 2018/4/12.
 */
public class MyLink implements MyDataStr {

    MyNode head;
    int size;

    public static void main(String[] args) {
        MyLink myLink = new MyLink();
        myLink.add("ss1");
        myLink.add("2");
        myLink.add("ss3");

        myLink.delete();
        myLink.add("ss4");

        System.out.println(myLink.find("2"));
        System.out.println(myLink.size());
        myLink.display();
    }

    public void add(Object data) {
        MyNode newNode = new MyNode(data);
        if (head == null) {
            head = newNode;
        } else {
            newNode.next = head;
            head = newNode;
        }
        size++;
    }

    public Object delete() {
        Object data = head.data;
        head = head.next;
        size--;
        return data;
    }

    public void delete(int i) {

    }

    public void delete(Object value) {
        //删除指定节点  只需要改变该节点的前后节点的指向


    }

    public Object get(int i) {
        MyNode x = head;

        for (int j = 0; j < i; j++) {
            x = head.next;
        }

        return x.data;
    }

    public MyNode find(Object value) {
        //遍历节点
        MyNode current = head;

        while (!current.data.equals(value)) {
            current = current.next;

            if (current == null) {
                break;
            }
        }
        return current;
    }

    public int search(Object value) {
        return 0;
    }

    public void display() {
        MyNode x = head;
        for (int j = 0; j < size; j++) {
            System.out.println(x.data);
            x = x.next;
        }
    }

    public int size() {
        return size;
    }

    private class MyNode {
        Object data;
        MyNode next;

        public MyNode(Object data) {
            this.data = data;
        }

        @Override
        public String toString() {
            return ToStringBuilder.reflectionToString(this,ToStringStyle.JSON_STYLE);
        }
    }

}
package dataStructure;

import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;

/**
 * 二叉树  维护root及其左右子树  以第一个内容为root 然后根据大小比较后往子树中添加
 * on 2018/4/12.
 */
public class MyTree {

    public static void main(String[] args) {
        MyTree myTree = new MyTree();
        myTree.insert("d");
        myTree.insert("a");
        myTree.insert("z");
        myTree.insert("y");
        myTree.insert("b");

        myTree.display();
    }


    Node root;

    public Node find(Object data) {
        if (root == null) {
            return null;
        }

        Node current = root;

        while (current != null) {
            if (data.hashCode() > current.data.hashCode()) {
                current = root.right;
            } else if (data.hashCode() < current.data.hashCode()) {
                current = root.left;
            } else {
                return current;
            }
        }

        return null;
    }


    public boolean insert(Object data) {
        Node newNode = new Node(data);

        if (root == null) {
            root = newNode;
            return true;
        }

        Node current = root;
        Node parentNode = null;
        while (current != null) {
            parentNode = current;
            if (data.hashCode() > current.data.hashCode()) {
                /*current = current.right;
                if(current == null){
                    current = newNode;
                    return true;
                }*/
                current = current.right;
                if (current == null) {//左子节点为空,直接将新值插入到该节点
                    parentNode.right = newNode;
                    return true;
                }
            } else {
                /*Node right = current.left;
                if(right == null){
                    right = newNode;
                }else{
                    current = right;
                }
                return true;*/

                current = current.left;
                if (current == null) {//右子节点为空,直接将新值插入到该节点
                    parentNode.left = newNode;
                    return true;
                }
            }
        }

        return false;
    }

    public void display() {
        System.out.println("root:" + root);
        midDisplay(root);
    }

    private void midDisplay(Node node) {
        if (node != null) {
            midDisplay(node.left);
            System.out.println(node);
            midDisplay(node.right);
        }
    }


    public class Node {
        Object data;
        Node left;
        Node right;

        public Node(Object data, Node left, Node right) {
            this.data = data;
            this.left = left;
            this.right = right;
        }

        public Node(Object data) {
            this.data = data;
        }

        public Node() {
        }

        @Override
        public String toString() {
            return (String) data;
        }
    }
}

hashtable hashCode确定在数组中的位置,equals确定是否需要放入数组下的链表

package dataStructure;

import javafx.util.Duration;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
import org.apache.commons.lang3.time.DateUtils;

import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.Period;
import java.util.Hashtable;

/**
 * 散列  参照hashTable源码
 * Created by EX-ZHOUXIAOWEI004 on 2018/4/12.
 */
public class MyHashTable<K,V>{
    private Entry<?,?>[]  table;//存放数据
    private transient int count;
    private int threshold;//容量
    private float loadFactor;//负载因子
    private transient int modCount = 0;//元素个数

    public static void main(String[] args) {
        new MyHashTable<String,String>(10,1);

    }
    public MyHashTable(int initialCapacity, float loadFactor) {
        //参数检测忽略掉了 直接初始化

        this.loadFactor = loadFactor;
//        table = new Entry<?,?>[initialCapacity];
        threshold = (int)Math.min(initialCapacity * loadFactor, Integer.MAX_VALUE - 8 + 1);
    }


    public synchronized V put(K key, V value){
        Entry<?,?> tab[] = table;//成员变量 赋值给局部变量  成员变量存在堆,局部存在栈  栈的数据操作更快
        int hash = key.hashCode();
        int index = (hash & 0x7FFFFFFF) % tab.length;//在table中的下标  或者叫位桶
        Entry<K,V> entry = (Entry<K,V>)tab[index];//取到当前位桶的entry   而ertry是一个链表

        //遍历这个entry链表 确认否存在这个key
        for (;entry != null; entry = entry.next){
            if (key.equals(entry.key)) {
                V old = entry.value;
                entry.value = value;
                return old;
            }
        }

        //如果不存在这个key
        addEntry(hash,key,value,index);


        return value;
    }

    private void addEntry(int hash, K key, V value, int index) {
        //确认是否需要扩容

        modCount++;
        Entry<?,?> tab[] = table;


        //取出index下的entry,然后新建一个entry指向原有的entry
        Entry<K, V> oldEntry = (Entry<K, V>) tab[index];
        Entry<K, V> newEntry = new Entry<K, V>(hash, key, value, oldEntry);//新的entry指向原有的entry
        tab[index] = newEntry;

        count++;


    }


    private class Entry<K,V>{
        final int hash;
        final K key;
        V value;
        Entry<K,V> next;

        public Entry(int hash, K key, V value, Entry<K, V> next) {
            this.hash = hash;
            this.key = key;
            this.value = value;
            this.next = next;
        }

        @Override
        public String toString() {
            return ToStringBuilder.reflectionToString(this, ToStringStyle.SIMPLE_STYLE);
        }
    }
}




java中的数据结构

常用结构

  1. Collection
    List

    • ArrayList 数组实现
    • Vector 其实就是数组实现的synchronized 版本
public synchronized E remove(int index) {
        modCount++;
        if (index >= elementCount)
            throw new ArrayIndexOutOfBoundsException(index);
        E oldValue = elementData(index);

        int numMoved = elementCount - index - 1;
        if (numMoved > 0)
            System.arraycopy(elementData, index+1, elementData, index,
                             numMoved);
        elementData[--elementCount] = null; // Let gc do its work

        return oldValue;
    }

LinkedList 双向链表 维持头和尾 Node first;/Node last

private static class Node<E> {
        E item;
        Node<E> next;
        Node<E> prev;

        Node(Node<E> prev, E element, Node<E> next) {
            this.item = element;
            this.next = next;
            this.prev = prev;
        }
    }

Set
HashSet 其内部维护一个HashMap 使用其中key的特性保证唯一性

public HashSet(Collection<? extends E> c) {
        map = new HashMap<>(Math.max((int) (c.size()/.75f) + 1, 16));
        addAll(c);
    }

TreeSet 其内部也维护一个TreeMap

Map

 HashMap 数组+链表(+红黑树java8)
 TreeMap 红黑树 

Queen 队列

ArrayBlockingQueue
LinkedBlockingQueue

线程安全的结构

Collections集合工具也提供内部类SynchronizedList/SynchronizedMap 其本质是利用装饰者模式,给原方法加上synchronized 悲观锁

 static class SynchronizedList<E>
        extends SynchronizedCollection<E>
        implements List<E> {
      final List<E> list;
      public void add(int index, E element) {
            synchronized (mutex) {list.add(index, element);}
        }
        public E remove(int index) {
            synchronized (mutex) {return list.remove(index);}
        }
}

1.5以后的java.util.concurrent并发包下的提供了线程安全的各种list/map,其利用的是CAS乐观锁
put时会调用compareAndSwapObject 这是个native方法,而get不会调用

    static final <K,V> boolean casTabAt(Node<K,V>[] tab, int i,
                                        Node<K,V> c, Node<K,V> v) {
        return U.compareAndSwapObject(tab, ((long)i << ASHIFT) + ABASE, c, v);
    }

[数据结构动态可视化](https://visualgo.net/zh

猜你喜欢

转载自blog.csdn.net/Wen_ching_zhou/article/details/80030860