1 Star 0 Fork 174

让我冷静一下吧 / Java-learning

forked from 程序员大彬 / Java-learning 
加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
该仓库未声明开源许可证文件(LICENSE),使用请关注具体项目描述及其代码上游依赖。
克隆/下载
数据结构.md 8.29 KB
一键复制 编辑 原始数据 按行查看 历史
Tysondai 提交于 2021-09-12 00:44 . update数据结构与算法

各种数据结构应用场景

  • 栈:逆序输出;语法检查,符号成对判断;方法调用

  • 二叉树:表达式树

  • B+/B-树:文件系统;数据库索引

  • 哈夫曼树:数据压缩算法

  • 哈希表:提高查找性能

  • 红黑树:大致平衡的二叉查找树,相对AVL树,插入删除结点较快,查找性能没有提升

    AVL树

平衡二叉搜索树,它是一 棵空树或它的左右两个子树的高度差的绝对值不超过1。

  • 左左单旋转 在这里插入图片描述

  • 左右双旋转 在这里插入图片描述

  • 四种旋转情况

    在这里插入图片描述

B树

也称B-树,属于多叉树又名平衡多路查找树。

规则:

  • 1<子节点数<=m,m代表一个树节点最多有多少个查找路径
  • 每个节点最多有m-1个关键字,非根节点至少有m/2个关键字,根节点最少可以只有1个关键字
  • 每个节点都有指针指向子节点,指针个数=关键字个数+1,叶子节点指针指向null

三叉树:

B-树的特性:

  1. 关键字集合分布在整颗树中;
  2. 任何一个关键字只出现在一个节点中;
  3. 搜索有可能在非叶子结点结束;

B+树是B-树的变体,也是一种多路搜索树。B+的搜索与B-树基本相同,区别是B+树只有达到叶子结点才命中,B-树可以在非叶子结点命中。B+树更适合文件索引系统。

B-和B+树的区别

  • B+树的非叶子结点不包含data,叶子结点使用链表连接,便于区间查找和遍历。B-树需要遍历整棵树,范围查询性能没有B+树好。
  • B-树的非树节点存放数据和索引,搜索可能在非叶子结点结束,访问更快。

红黑树

红黑树是对AVL树的优化,只要求部分平衡,用非严格的平衡来换取增删节点时候旋转次数的降低,提高了插入和删除的性能。查找性能并没有提高,查找的时间复杂度是O(logn)。红黑树通过左旋、右旋和变色维持平衡。

对于插入节点,AVL和红黑树都是最多两次旋转来实现平衡。对于删除节点,avl需要维护从被删除节点到根节点root这条路径上所有节点的平衡,旋转的量级为O(logN),而红黑树最多只需旋转3次。

  • 特性: (1) 每个节点或者是黑色,或者是红色。 (2) 根节点和叶子节点是黑色,叶子节点为空。 (4)红色节点的子节点必须是黑色的。 (5) 从一个节点到该节点的子孙节点的所有路径上包含相同数目的黑节点,保证没有一条路径会比其他路径长一倍。

  • 优点:相比avl树,红黑树插入删除的效率更高。红黑树维持红黑性质所做的红黑变换和旋转的开销,相较于avl树维持平衡的开销要小得多。

  • 应用:主要用来存储有序的数据,Java中的TreeSet和TreeMap都是通过红黑树实现的。 在这里插入图片描述

图由顶点集(vertex set)和边集(edge set)所组成。

图的存储结构有邻接矩阵、邻接表和边集数组三种。 邻接矩阵 邻接表

下面给出建立图的邻接表中所使用的边结点类的定义

     public class EdgeNode {     //定义邻接表中的边结点类型
         int adjvex;             //邻接点域
         int weight;             //边的权值域,假定为整型,对于无权图,边的权值为1
         EdgeNode next;          //指向下一个边结点的链接域
         public EdgeNode(int adj, EdgeNode nt) 
         {     //对无权图中的边结点进行初始化
             adjvex=adj; next=nt; weight=1;
         }
         public EdgeNode(int adj, int wgt, EdgeNode nt) 
         {     //对有权图中的边结点进行初始化
             adjvex=adj; next=nt; weight=wgt;
         }
     }

图的接口类定义如下:

public interface Graph
     {
         boolean createGraph(EdgeElement[]d);  //根据边集数组参数d建立一个图
         int graphType();                   //返回图的类型
         int vertices();                    //返回图中的顶点数
         int edges();                       //返回图中的边数
         boolean find(int i, int j);        //从图中查找一条边(i,j)是否存在
         boolean putEdge(EdgeElement theEdge); //向图中插入一条边theEdge
         boolean removeEdge(int i, int j);     //从图中删除一条边(i,j)
         int degree(int i);                 //返回顶点i的度
         int inDegree(int i);               //返回顶点i的入度
         int outDegree(int i);              //返回顶点i的出度
         void output();                     //以图的顶点集和边集的形式输出一个图
         void depthFirstSearch(int v);      //从顶点v开始深度优先搜索遍历图
         void breadthFirstSearch(int v);    //从顶点v开始广度优先搜索遍历图
         void clearGraph();                 //清除图中的所有内容
     }

深度优先遍历

    private void dfs(int i, boolean[] visited) {
        System.out.printl(i + " ");
        visited[i] = true;
        EdgeNode p = a[i];
        while(p != null) {
            int j = p.adjvex;
            if(!visited[j]) {
                dfs(j, visited);
            }
            p = p.next;
        }
    }

广度优先搜索

 private void bfs(int i, boolean[] visited) {
        LinkedList<Integer> queue = new LinkedList<>();
        System.out.print(i + " ");
        visited[i] = true;
        queue.offer(i);
        while(!queue.isEmpty()) {
            int k = queue.poll();
            EdgeNode p = a[k];

            while(p != null) {
                int j = p.adjvex;
                 if(!visited[j]) {
                     System.out.print(j + " ");
                     visited[j] = true;
                     queue.offer(j);
                 }
                 p = p.next;
            }
        }
    }

二分查找

    public int binarySearch(int[] arr, int target) {
        if (arr == null || arr.length <= 1) {
            return -1;
        }

        int left = 0;
        int right = arr.length - 1;

        while (left <= right) {
            int mid = (left + right) >>> 1;
            if (arr[mid] > target) {
                right = mid - 1;
            } else if (arr[mid] < target) {
                left = mid + 1;
            } else {
                return mid;
            }
        }

        return -1;
    }
Java
1
https://gitee.com/zhangaop/Java-learning.git
git@gitee.com:zhangaop/Java-learning.git
zhangaop
Java-learning
Java-learning
master

搜索帮助