水文:数据结构小记

水文:数据结构小记

未完,明天继续更。

参考

GeeksforGeeks: https://www.geeksforgeeks.org/data-structures/

一)数据结构类型

图片来源(GeeksforGeeks

  1. 数组,array
  2. 链表,link
  3. 栈,stack
  4. 队列,queue
  5. 树,tree

  6. 哈希表,hash
  7. 堆,heap
  8. 图,graph

二)存储结构

逻辑结构

  1. 集合结构
  2. 线性结构
  3. 树形结构
  4. 图形结构

物理结构

  1. 顺序存储结构:相邻元素地址相邻
  2. 链式存储结构:相邻元素通过指针相连

三)note

1. 数组:顺序表

表有一个size属性,记录当前存储元素的个数;
表有一个capacity属性,记录当前表的容量;

  • 空:size == 0
  • 满:size == capacity
  • 长度:size
  • 扩容:size == capacity时,发生的行为。数组申请一个更大的空间,将原来的数据复制到新空间
  • 基本操作:非尾端增删,会发生数据移动;get操作直接通过计算地址获取指定位置元素,比较快

2. 链表

节点:Node { next; data }
表由节点Node,通过Node的next指针域相连接;
表有一个head,代表链表的头,初始化为 head = new Node,其next为null,表明当前表没有元素
表有一个size属性,记录当前存储元素的个数;

  • 空:size == 0.或head.next为null
  • 长度:size.或从head.next开始计数,data域不为空则加1,然后判断下一个
  • 基本操作:非头节点处增删,需要从head移动到指定索引节点处;get操作需要从head开始移动,较慢

3. 栈

栈是只支持在一端(称为栈顶)进行添加、删除操作的表;
初始状态:top = 0。按照size来理解即可;

  • 支持操作:进栈、出栈、取栈顶元素

4. 队列

队列是只支持在一端进、另一端出操作的表;
尾进,头出;

  • 类型:普通队列,循环队列,优先级队列(基于堆)

建议使用:链表队列、循环队列

1. 普通队列(数组实现):front = rear = 0
	进,rear后移;出,front后移。
	front前面的元素如何使用?
		方法一:数组移动,效率太低;
		方法二:循环数组,建议。
		方法三:改用链表实现
2. 循环数组:front = rear = 0
	空间可以充分利用,如何判断满和空?
		方法一:count记录队列元素个数。空count==0,满count==size
		方法二:数组空出一个位置,标记队列是否已满。空rear==front,满(rear+1)%SIZE==front

5. 树

存储:双亲表示法;孩子表示法;孩子兄弟表示法
类型:树、二叉树、线索二叉树、哈夫曼树

平衡二叉树:AVL、红黑树
多路平衡树:B树、B+树、B*树
Trie树:字典树。
	字符串的公共前缀。

常见算法:层次遍历;前中后序遍历;树 森林 二叉树的转换算法

// 数组
class TreeNode<E> {
	int leftIndex;
	int rightIndex;
	E value;
}
// 链表
class TreeNode<E> {
    TreeNode<E> left;
    TreeNode<E> right;
    E value;
}

6. 哈希表

7. 图

存储:邻接矩阵;邻接表
类型:有向图、无向图
常见算法:

  1. 遍历算法:广度优先遍历 BFS、深度优先遍历 DFS
  2. 最小生成树算法:普利姆算法 Prime、克鲁斯卡尔算法 Kruskal
  3. 最短路径算法:迪杰斯特拉算法 Dijkstra、弗洛伊德算法 Floyd
  4. 拓扑排序
  5. 关键路径

四)查找和排序

查找算法

  1. 顺序表查找
  2. 有序表查找:折半查找、插值查找、斐波那契查找
  3. 线性索引查找:稠密索引、分块索引、倒排索引
  4. 二叉排序树
  5. 平衡二叉树:AVL
  6. 多路查找树:B树、B+树
  7. 散列表查找

排序算法:内排序

  1. 冒泡排序
  2. 简单选择排序
  3. 直接插入排序
  4. 希尔排序
  5. 堆排序
  6. 归并排序
  7. 快速排序

code

interface MyList<E> {
    void add(E e);
    void add(int index, E e);
    E delete(int index);
    E update(int index, E value);
    E get(int index);
}

class MyArrayList<E> implements MyList<E> {
    private E[] element;
    private int size;

    private void grow() {
        // TODO 扩容
    }

    /*
    1. size检查
    2. 添加
    3. 更新size
     */
    public void add(E e) {
        if (size == element.length) {
            grow();
        }
        element[size++] = e;
    }
    /* 在index前面,增加E e。index取值范围:[0, size]
    1.
     */
    public void add(int index, E e) {
        if (index < 0 || index > size) {
            return;
        }
        if (size == element.length) {
            grow();
        }
        int moved = size - index - 1;
        if (moved > 0) {
            System.arraycopy(element, index, element, index + 1, moved);
        }
        element[index] = e;
        size++;
    }

    /*
    1. 范围检查
    2. 删除并移动
    3. 更新size
    3. 返回index old值
     */
    public E delete(int index) {
        if (index < 0 || index >= size) {
            return null;
        }

        E result = element[index];
        int moved = size - index - 1;
        if (moved > 0) {
            System.arraycopy(element, index + 1, element, index, moved);
        }
        element[--size] = null;
        return result;
    }
    /*
    1. 范围检查
    2. 更新
    3. 返回index old值
     */
    public E update(int index, E value) {
        if (index < 0 || index >= size) {
            return null;
        }
        E result = element[index];
        element[index] = value;
        return result;
    }

    public E get(int index) {
        if (index < 0 || index >= size) {
            return null;
        }
        return element[index];
    }
}

class MyLinkedList<E> implements MyList<E> {
    static class Node<E> {
        E data;
        Node<E> next;
        public Node() {}
        public Node(E data) {
            this(data, null);
        }
        public Node(E data, Node<E> next) {
            this.data = data;
            this.next = next;
        }
    }
    private Node<E> head;
    private int size;

    // 头插法
    public void add(E e) {
        if (head == null) {
            head = new Node<E>();
        }
        Node<E> node = new Node<E>(e, head.next);
        head.next = node;
        size++;
    }
    public void add(int index, E e) {
        // TODO
    }

    public E delete(int index) {
        if (head == null || index < 0 || index >= size) {
            return null;
        }
        Node<E> next = head;
        Node<E> p = head.next;
        while (p != null && index > 0) {
            next = p;
            p = p.next;
            index--;
        }
        E result = null;
        if (p != null) {
            result = p.data;
            next.next = p.next;
            p = null;
        }
        size--;
        return result;
    }
    public E update(int index, E value) {
        if (head == null || index < 0 || index >= size) {
            return null;
        }
        Node<E> p = head.next;
        while (p != null && index > 0) {
            p = p.next;
            index--;
        }
        E result = null;
        if (p != null) {
            result = p.data;
            p.data = value;
        }
        return result;
    }
    public E get(int index) {
        if (head == null || index < 0 || index >= size) {
            return null;
        }
        Node<E> p = head.next;
        while (p != null && index > 0) {
            p = p.next;
            index--;
        }
        return p != null ? p.data : null;
    }
}

interface Stack<E> {
    void push(E e);
    void pop();
    E top();
}
class MyArrayStack<E> implements Stack<E> {
    private E[] element;
    private int top = -1;

    public void push(E e) {
        if (top == element.length - 1) {
            return;
        }
        element[++top] = e;
    }

    public void pop() {
        if (top == -1) {
            return;
        }
        element[top--] = null;
    }

    public E top() {
        if (top == -1) {
            return null;
        }
        return element[top];
    }
}

interface Queue<E> {
    boolean offer(E e);
    boolean poll();
    E peek();
}
class MyArrayQueue<E> implements Queue<E> {
    private E[] element;
    private int head;
    private int tail;

    /*
    初始,队列head=tail=0
    空: head == tail
    满:(tail + 1) % element.length == head
    入队:tail + 1
    出队:head - 1
    tail,所在位置无值
     */

    public boolean offer(E e) {
        if ((tail + 1) % element.length == head) {
            return false;
        }
        element[tail] = e;
        tail = (tail + 1) % element.length;
        return true;
    }

    public boolean poll() {
        if (head == tail) {
            return false;
        }
        element[head] = null;
        head = (head + 1) % element.length;
        return true;
    }

    public E peek() {
        if (head == tail) {
            return null;
        }
        return element[head];
    }
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值