美文网首页
1:什么叫数据结构 什么叫算法

1:什么叫数据结构 什么叫算法

作者: _River_ | 来源:发表于2021-05-13 00:38 被阅读0次
    学习连接来源于算法小抄:https://labuladong.gitee.io/algo/
    
    1:什么叫数据结构
    数据结构的存储方式只有两种:数组(顺序存储)和链表(链式存储)。
    
    ArrayList   LinkedList
    Array   英文为  数组 
    Linked 英文为  链接
    List     英文为  集合 清单
    
    因此建议以后描述为:
    基本数组:最基本的数组 int[ ] array ;
    数组集合(数组):ArrayList
    链表集合(链表):LinkedList
    
    特别是针对数组建议区分描述;
    

    那么栈、队列、散列表(Hash表)、堆、树、图  这些数据结构呢?
    
    实际上那些都属于「上层建筑」,而数组和链表才  是「结构基础」。因为那些多样化的数据结构,究其源头,都是在链表或者数组上的特殊操作,API 不同而已。
    
    比如说「队列」、「栈」这两种数据结构既可以使用链表也可以使用数组实现。
    用数组实现,就要处理扩容缩容的问题;用链表实现,没有这个问题,但需要更多的内存空间存储节点指针。
        
    「散列表」(Hash表)就是通过散列函数把键映射到一个大数组里,
    而且对于解决散列冲突的方法:
    方法一:拉链法要链表特性,操作简单,但需要额外的空间存储指针;
    方法二:线性探查法就需要数组特性,以便连续寻址,不需要指针的存储空间,但操作稍微复杂些;
          
     [堆]
    用数组实现就是「堆」,因为「堆」是一个完全二叉树,用数组存储不需要节点指针,操作也比较简单;
    
    「树」   
    用链表实现就是很常见的那种「树」,因为不一定是完全二叉树,所以不适合用数组存储。
    为此,在这种链表「树」结构之上,又衍生出各种巧妙的设计,比如二叉搜索树、AVL 树、红黑树、区间树、B 树等等,以应对不同的问题。
         
    「图」的两种表示方法,邻接矩阵就是二维数组。邻接表就是链表。
    邻接矩阵判断连通性迅速,并可以进行矩阵运算解决一些问题,但是如果图比较稀疏的话很耗费空间。
    邻接表比较节省空间,但是很多操作的效率上肯定比不过邻接矩阵。
    
    
    数组由于是紧凑连续存储,可以随机访问,通过索引快速找到对应元素,而且相对节约存储空间。
    但正因为连续存储,内存空间必须一次性分配够,所以说数组如果要扩容,需要重新分配一块更大的空间,再把数据全部复制过去,时间复杂度 O(N);
    而且你如果想在数组中间进行插入和删除,每次必须搬移后面的所有数据以保持连续,时间复杂度 O(N)。
    
    
    链表因为元素不连续,而是靠指针指向下一个元素的位置,所以不存在数组的扩容问题;
    如果知道某一元素的前驱和后驱,操作指针即可删除该元素或者插入新元素,时间复杂度 O(1)。
    但是正因为存储空间不连续,你无法根据一个索引算出对应元素的地址,所以不能随机访问;而且由于每个元素必须存储指向前后元素位置的指针,会消耗相对更多的储存空间。
    
    2:什么叫算法
    所谓的算法就是基于对应的数据结构做对应操作
    
    对于任何数据结构,其基本操作无非遍历 + 访问,再具体一点就是:增删查改。
    数据结构种类很多,但它们存在的目的都是在不同的应用场景,尽可能高效地增删查改。
    

    数组遍历框架,典型的线性迭代结构:
    
    void traverse(int[] arr) {
        for (int i = 0; i < arr.length; i++) {
            // 迭代访问 arr[i]
        }
    }
    
    链表遍历框架,兼具迭代和递归结构:  
    
    /* 基本的单链表节点 */
    class ListNode {
        int val;
        ListNode next;
    }
    
    void traverse(ListNode head) {
        for (ListNode p = head; p != null; p = p.next) {
            // 迭代访问 p.val
        }
    }
    
    void traverse(ListNode head) {
        // 递归访问 head.val
        traverse(head.next);
    }
    
    
    二叉树遍历框架,典型的非线性递归遍历结构:
    
    /* 基本的二叉树节点 */
    class TreeNode {
        int val;
        TreeNode left, right;
    }
    
    void traverse(TreeNode root) {
        traverse(root.left);
        traverse(root.right);
    }
    
    
    二叉树框架可以扩展为 N 叉树的遍历框架:
    
    /* 基本的 N 叉树节点 */
    class TreeNode {
        int val;
        TreeNode[] children;
    }
    
    void traverse(TreeNode root) {
        for (TreeNode child : root.children)
            traverse(child);
    }
    
    
    3:如何快速的提高对数据结构以及算法的理解
    先刷二叉树呢,因为二叉树是最容易培养框架思维的,而且大部分算法技巧,本质上都是树的遍历问题。
    不要小看这几行破代码,几乎所有二叉树的题目都是一套这个框架就出来了。
    
    void traverse(TreeNode root) {
        // 前序遍历
        traverse(root.left)
        // 中序遍历
        traverse(root.right)
        // 后序遍历
    }
    

    不要心急  先保留问题 等学完再回到这里
    不要心急  先保留问题 等学完再回到这里
    不要心急  先保留问题 等学完再回到这里
    
    int ans = INT_MIN;
    int oneSideMax(TreeNode* root) {
        if (root == nullptr) return 0;
        int left = max(0, oneSideMax(root->left));
        int right = max(0, oneSideMax(root->right));
        ans = max(ans, left + right + root->val);
        return max(left, right) + root->val;
    }
    
    
    TreeNode buildTree(int[] preorder, int preStart, int preEnd, 
        int[] inorder, int inStart, int inEnd, Map<Integer, Integer> inMap) {
    
        if(preStart > preEnd || inStart > inEnd) return null;
    
        TreeNode root = new TreeNode(preorder[preStart]);
        int inRoot = inMap.get(root.val);
        int numsLeft = inRoot - inStart;
    
        root.left = buildTree(preorder, preStart + 1, preStart + numsLeft, 
                              inorder, inStart, inRoot - 1, inMap);
        root.right = buildTree(preorder, preStart + numsLeft + 1, preEnd, 
                              inorder, inRoot + 1, inEnd, inMap);
        return root;
    }
    
    
    void traverse(TreeNode* node) {
        if (!node) return;
        traverse(node->left);
        if (node->val < prev->val) {
            s = (s == NULL) ? prev : s;
            t = node;
        }
        prev = node;
        traverse(node->right);
    }
    
    

    相关文章

      网友评论

          本文标题:1:什么叫数据结构 什么叫算法

          本文链接:https://www.haomeiwen.com/subject/pmttjltx.html