zoukankan      html  css  js  c++  java
  • 数据结构相关知识整理

    用两个栈实现一个队列

    栈:后进先出

    队列:先进先出

    要使用两个栈实现队列(先进先出),主要思路是

    1.插入一个元素:直接将元素插入stack1即可。
    2.删除一个元素:当stack2不为空时 ,直接弹出栈顶元素,当stack2为空时,将stack1元素逐个弹出并压入stack2,然后再弹出栈顶元素。

    用我的话说就是两个先进后出就变成先进先出了

    具体可参考 https://www.cnblogs.com/clwsec/p/11586972.html

    平衡二叉树

    平衡树(Balance Tree,BT) 指的是,任意节点的子树的高度差都小于等于1。常见的符合平衡树的有,B树(多路平衡搜索树)、AVL树(二叉平衡搜索树)等。

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

    具体可参考 https://www.cnblogs.com/zhangbaochong/p/5164994.html

    双向链表

    双向链表也叫双链表,是链表的一种,它的每个数据结点中都有两个指针,分别指向直接后继和直接前驱。所以,从双向链表中的任意一个结点开始,都可以很方便地访问它的前驱结点和后继结点。

    实现链表翻转有以下两种方法:

    • 建立新链表,依次从旧链表中复制节点,并将其作为头。空间复杂度为O(N)
    • 原地翻转 。空间复杂度为O(1)

    typedef int eleType;
    typedef struct Node{
        eleType ele;
        struct Node* next;
    }Node, *pNode;

    pNode node = (pNode)malloc(sizeof(pNode));
            node->ele = i;
            node->next = NULL;
            temp->next = node;

    详见 https://blog.csdn.net/kid1ing/article/details/67638061

    二叉树遍历方法

    给定 先序+中序 or 后序+中序 可以唯一确定一颗二叉树

    1. 而 先序+后序 不能
    2.  
        A
    3.  
      /
    4.  
      B
    5.  
      前序遍历: AB, 后序遍历: BA
    6.  
      A
    7.  
    8.  
        B
    9.  
      前序遍历: AB, 后序遍历: BA
       
      海量数据处理 - 10亿个数中找出最大的10000个数(top K问题)

      方法一、先拿10000个数建堆,然后一次添加剩余元素,如果大于堆顶的数(10000中最小的),将这个数替换堆顶,并调整结构使之仍然是一个最小堆,这样,遍历完后,堆中的10000个数就是所需的最大的10000个。建堆时间复杂度是O(mlogm),算法的时间复杂度为O(nmlogm)(n为10亿,m为10000)。

          方法二(优化的方法):可以把所有10亿个数据分组存放,比如分别放在1000个文件中。这样处理就可以分别在每个文件的10^6个数据中找出最大的10000个数,合并到一起在再找出

      最终的结果。

      哈夫曼树

      哈夫曼树又称最优二叉树,是一种带权路径长度最短的二叉树。所谓树的带权路径长度,就是树中所有的叶结点的权值乘上其到根结点的路径长度(若根结点为0层,叶结点到根结点的路径长度为叶结点的层数)。树的带权路径长度记为WPL=(W1*L1+W2*L2+W3*L3+...+ Wn*Ln),N个权值Wi(i=1,2,...n)构成一棵有N个叶结点的二叉树,相应的叶结点的路径长度为Li(i=1,2,...n)。可以证明哈夫曼树的WPL是最小的。
              构造哈夫曼树的算法如下:
              1)对给定的n个权值{W1,W2,W3,...,Wi,...,Wn}构成n棵二叉树的初始集合F={T1,T2,T3,...,Ti,..., Tn},其中每棵二叉树Ti中只有一个权值为Wi的根结点,它的左右子树均为空。
              2)在F中选取两棵根结点权值最小的树作为新构造的二叉树的左右子树,新二叉树的根结点的权值为其左右子树的根结点的权值之和。
              3)从F中删除这两棵树,并把这棵新的二叉树同样以升序排列加入到集合F中。
              4)重复2)和3),直到集合F中只有一棵二叉树为止。

      哈夫曼树应用-哈夫曼编码

      哈夫曼树的一个经典应用就是哈夫曼编码。在数据通信中,经常需要将传送的文字转换成二进制字符串,这个过程就是编码。哈夫曼编码是一种变长的编码方案,其核心就是使频率越高的码元(这个词不知用的是否准确,就是要编码的对象,可以是字符串等等了)采用越短的编码。编码过程就根据不同码元的频率(相当于权值)构造出哈夫曼树,然后求叶子节点到根节点的路径,其中节点的左孩子路径标识为0,右孩子路径标识为1。对于上面的例子,权值为1的节点编码为000,权值为3的节点编码为001,权值为5的节点编码为01,权值为7的节点编码为1。

      详见 https://www.cnblogs.com/aaron911/p/11058017.html

      单链表特点

      当访问过一个节点后,只能接着访问他的后继节点,而无法访问前驱节点。

      优先队列

      普通的队列是一种先进先出的数据结构,元素在队列尾追加,而从队列头删除。

      在优先队列中,元素被赋予优先级。当访问元素时,具有最高优先级的元素最先删除。优先队列具有最高级先出 (first in, largest out)的行为特征。

      首先要包含头文件#include<queue>, 他和queue不同的就在于我们可以自定义其中数据的优先级, 让优先级高的排在队列前面,优先出队。

      优先队列具有队列的所有特性,包括队列的基本操作,只是在这基础上添加了内部的一个排序,它本质是一个堆实现的。

      定义:priority_queue<Type, Container, Functional>
      Type 就是数据类型,Container 就是容器类型(Container必须是用数组实现的容器,比如vector,deque等等,但不能用 list。STL里面默认用的是vector),Functional 就是比较的方式。

      当需要用自定义的数据类型时才需要传入这三个参数,使用基本数据类型时,只需要传入数据类型,默认是大顶堆。

      //升序队列,小顶堆
      priority_queue <int,vector<int>,greater<int> > q;
      //降序队列,大顶堆
      priority_queue <int,vector<int>,less<int> >q;
      
      //greater和less是std实现的两个仿函数(就是使一个类的使用看上去像一个函数。其实现就是类中实现一个operator(),这个类就有了类似函数的行为,就是一个仿函数类了)

      详见 https://www.cnblogs.com/huashanqingzhu/p/11040390.html

      堆和队列的区别

      队列是先进先出,于堆而言却没有这个特性,两者都是存放临时数据的地方

      栈也称为堆栈,是一种线性表。

      堆栈的特性: 最先放入堆栈中的内容最后被拿出来,最后放入堆栈中的内容最先被拿出来, 被称为先进后出、后进先出。

  • 相关阅读:
    CentOS的SSH,Putty配置说明
    关于QString::toWCharArray 无法解析的外部符号
    CentOS最常用命令及快捷键整理
    Ali相关面试题
    C#几个例子[静态构造函数,继承,虚方法]
    SQL 2005 中查询或执行另外的数据库操作的方法
    DataTable Select Top
    SQL中行列转换 Pivot UnPivot
    ASP.NET页面生命周期描述
    Jquery checkbox, select 取值
  • 原文地址:https://www.cnblogs.com/Annetree/p/13511484.html
Copyright © 2011-2022 走看看