【数据结构】数据结构知识点总结

1.绪论

  • 在数据结构中,从逻辑上把数据结构分成 线性结构 和 非线性结构
  • 数据结构在计算机内存中的表示是指 数据的存储结构
  • 数据项 是数据的最小单位, 数据元素 是数据的基本单位
  • 计算机所处理数据一般具有某种内在联系,这里是指 数据元素与数据元素之间存在某种关系
  • 算法分析的目的是 分析算法的效率以求改进
  • 在存储数据是,不仅要考虑存储各数据元素的值,而且还要存储 数据元素之间的关系
  • 算法分析的主要任务是分析 算法的执行时间和问题规模之间的关系
  • 数据的运算   效率与采用何种存储结构有关
  • 算法的计算量的大小称为算法的  时间复杂度
  • 连续存储分配时,存储单元的地址  一定连续
  • 数据的逻辑结构指 数据元素之间的逻辑关系
  • 一个数据结构在计算中的   表示   称为存储结构
  • 数据的物理逻辑只要包括  顺序存储结构  的表示和  链式存储结构  的表示
  • 数据逻辑结构包括 集合 、线性结构、树 和 图 四种 ,树结构和图结构统称为 非线性结构
  • 顺序存储方法把逻辑上  相邻的元素  存储在物理位置 相邻的存储单元里 ; 链式存储方法中结点间的逻辑关系是由  指针域  表示的。
  • 数据结构研究的是  逻辑结构和物理结构  以及它们之间的相互关系,并对于这种结构定义相应的 运算 ,设计出相应的 算法。
  • 算法的执行时间是 问题规模n 的函数。
  • 简述数据的逻辑结构和存储结构的关系。

         答:在数据结构中,逻辑结构和存储结构是密切相关的,存储结构不仅将数据元素存储到计算机中,而且还要表示各数据元素之间的逻辑关系。逻辑结构与计算机无关,存储结构是数据元素之间的关系在计算机中的表示。通常情况下,一种逻辑结构可以有多种存储结构,例如,线性结构可以采取顺序存储结构或链式存粗结构表示。

  • 数据结构和数据类型有什么区别?

        答:数据结构是相互间存在一种或多种特定关系的数据元素的集合,一般包括三个方面的内容:数据的逻辑结构、存储结构和多数据的运算。数据类型是一个值得集合和定义在这个值集上的一组操作的总称。数据结构重点考虑元素之间的关系,数据类型重点考虑数据的个体特征。

  • 当为解决某一问题已经选定其数据的逻辑结构后,选择数据的存储结构时,应从哪些方面考虑?

       答:通常从两个方面考虑:第一是算法实现的存储空间复杂度;第二是算法执行的时间复杂度。若存储空间难以确定,宜选择链式存储结构,否则选择顺序存储结构。若插入、删除操作频繁,则选链式存储结构,否则选择顺序存储结构。

线性表 

  • 链表具备的特点是 插入删除不需要 移动元素  、 不必事先估算存储空间 、 所需空间与长度成正比
  • 如果最常用的操作是取第 i 个 结点及其前驱,则采用  顺序表 存储方法最节省时间
  • 线性表是具有n个  数据元素  的有限序列 (n >= 0)
  • 线性表的顺序存储结构是一种  随机存储的存储结构
  • 单链表中增加一个头结点的目的是为了   方便运算的实现
  • 不带头结点的单链表(头指针为h)为空的条件是   h==NULL
  • 带头结点的单链表(头指针为h)为空的条件是  h->next==NULL
  • 带头结点的循环双向链表(头指针为L)为空的条件是  L->next==L
  • 非空的循环单链表(头指针为head)的尾结点(由p指向)满足  p->next==head
  • 设一个链表最常用的操作是在末尾插入结点和删除尾结点,则选用  带头结点的双循环链表  最节省时间。
  • 若某线性表最常用的操作存取任意指定序号的元素和在表尾进行插入和删除,则选用 顺序表  的存储方式最节省时间。
  • 若长度为n的线性表采用顺序存储结构,在第i个位置插入一个新元素的算法的时间复杂度为  O(n)
  • 对于顺序存储的线性表,访问结点和增加、删除结点的时间复杂度为  O(1)O(n)
  • 线性表以链式方式存储,访问第i个结点的时间复杂度为  O(n)
  • 循环链表H尾结点p的特点是 p->next==H
  • 向一个长度为n的顺序表中的第i个元素之前插入一个元素时,需要向后移动 n-i+1      个元素。
  • 在一个长度为n的顺序表中删除第i个元素时,需要向前移动  n-i  个元素。
  • 在单链表中设置头结点的作用是  简化插入、删除算法    
  • 在单链中要删除某一指定结点,必须找到该结点的 直接前驱  结点。
  • 访问单链表中的结点,必须沿着  指针域    依次进行。
  • 在双链表中每个结点有两个指针域,一个指向 直接前驱结点   ,一个指向 直接后继结点    
  •   双向循环    链表中,删除最后一个结点的算法时间复杂度为O(1)。
  • 访问一个线性表中具有给定值的时间复杂度的数量级是  O(n)          
  • 由n个数据元素生成一个顺序表,若每次都调用插入算法把一个元素插入到表头,则整个算法的时间复杂度为   O(n)    ,若每次都调用插入算法把一个元素插入到表尾,则整个算法的时间复杂度为   O(n2)     
  •   双向       链表中,可以用表尾指针代替表头指针。
  • 根据n个数据元素建立对应的顺序表和单链表存储结构,其算法的时间复杂度最好的情况是  O(n)          ,最坏的情况是   O(n2)        
  • 求线性表的顺序存储和链式存储的长度的算法时间复杂度分别是  O(1)       O(n)    
  • 在一个带头结点的单链表中,在表头插入或删除与在其他位置插入或删除,其操作过程是否相同?    相同        
  • 在一个不带头结点的单链表中,在表头插入或删除与在其他位置插入或删除,其操作过程是否相同?   不相同         
  • 阐述顺序表和链表存储方式的特点。

    答:顺序表存储方式为数据分配连续的存储单元,数据元素按逻辑顺序依次存储到相应存储单元中,使得逻辑相邻的数据元素物理也相邻,因此可以实现随机访问线性表的数据元素,即数据访问的时间复杂度为O(1)。

    链表存储方式分配的存储单元可以不连续,通过每个结点的指针域来表示数据元素之间的逻辑关系,只能顺序访问线性表中的数据元素。

  • 若频繁地对一个线性表进行插入和删除操作,则该线性表宜采用何种存储结构,为什么?

    答:若频繁地对一个线性表进行插入和删除操作,则该线性表宜采用链式存储结构。因为链式存储结构在插入和删除数据元素时不需要移动数据元素,只需要修改结点的指针域就可以改变数据元素之间的逻辑关系。

  • 在单链表、双向循环链表和单循环链表中,若仅知道指针p指向某结点,不知道头指针,能否将结点p从相应的链表中删除?若可以,时间复杂度各为多少。

    答:要实现删除p结点的操作,必须找到其前驱结点,修改其指针域的值使其指向p的后继结点,以实现删除结点p。单链表不行,因为不知道头指针就无法找到结点p的前驱结点。双向循环链表和单循环链表可以可以实现删除p结点。单循环链表删除p结点的时间复杂度为O(n),双循环链表删除P结点的时间复杂度为O(1)。

  • 对链表设置头结点的作用是什么?

    答:对带头结点的链表,在表的任何结点之前插入结点或删除任何位置的结点,所要做的都是修改前一个结点的指针域,因为在带头结点的链表中任何元素结点都有前驱结点。如果没有头结点,在首元结点前插入结点或删除首元结点都要修改头指针,其算法要比带头结点的算法复杂些。

    其次,带头结点的链表结构,初始化后的头指针就固定了,除撤销算法外,所有算法都不会修改头指针,可以减少出错的可能性。

已知一个线性表用含头结点的单链表做存储结构,写一个算法求单链表的长度。

解:算法基本思想:从头结点的下一个结点开发,遍历单链表的每个结点,每遇到一个结点,结点计算器加1。

int listlenght(linklist L)
 { int length=0;
  P=L->next;
  while(p) 
    { length++;
      p=p->next;
      }
   return(length);
  }

已知一个顺序表L,其中的元素按值递增有序排列,设计一个算法插入一个值为x的元素后保持该顺序表仍然递增有序,且空间复杂度为0(1)。

void insertsq(sqlist L,elemtype x)
 { n=L.length-1;
   while(n>=0&&LT(x,L.elem[n])
      { L.elem[n+1]=L.elem[n];
       n--;
       }
L.elem[n+1]=x;
}
L.lenght++;
return;
}

写一个算法,从顺序表中删除值为x的所有元素。

void delallsq(Sqlist &L)
        { int i=0,j=0;
          while(j<L.length)
            { if(L.elem[j]!=x)
               L.elem[i++]=L.elem[j];
             j++;
             }
          L.longth=i;
          }

栈和队列

  • 对于栈操作的原则是  先进后出
  • 队列的先进先出特性是指  最后插入队列的元素总是最后被删除
  • 与顺序栈相比较,链栈有一个比较明显的优势是  通常不会出现栈满的情况
  • 栈和队列的共同点是  只允许在端点处进行插入和删除
  • 栈的特点是  后进先出  ,队列的特点是   先进先出;
  • 用单链表表示的链队列的队头在链表的  链头
  • 输入序列是ABC,若输出序列变为CBA,经过的栈操作为   push,push,push,pop,pop,pop
  • 栈在 递归调用,函数调用,表达式求值  应用
  • 设计一个判别表达式中左、右括号是否配对的算法,采用  栈  数据结构最佳。
  • 队列存放在A[0..M-1]中,则入队时的操作为   rear=(rear+1)%M
  • 队列存放在A[0..M-1]中,则出队时的操作为  front=(front+1)%M
  • 循环队列的最大容量为M,则队空的条件是  rear==front
  • 循环队列的最大容量为M,则队满的条件是   (rear+1)%M==front
  • 循环队列的引入,目的是为了克服  顺序队列的假溢出            
  • 区分循环队列的空与满有3种方法,它们是  少用一个元素   设空满标志  用计数器记录队列中元素个数      
  • 栈和队列的区别是  栈只能在表一端进行插入和删除操作,队列限制在表的一端进行插入操作,在另一端进行删除操作     
  • 设栈采取顺序存储结构,栈中已有i-1个元素,则第i个元素进栈操作的算法时间复杂度是  O(1)    
  • 若用不带头结点的单链表表示栈,则创建一个空栈要执行的操作是  top=NULL   
  • 如果栈的最大长度难以估计,最好使用  链栈       
  • 为什么说栈是一种后进先出表?

    答:因为栈是限定在表的一端进行插入和删除操作,所以后入栈的数据元素总是先出栈,所以说栈是一种后进先出表。

  • 对于一个栈,其输入序列是A,B,C,试给出全部可能的输出序列。

    答:可能的出栈序列是:ABC、ACB、BAC、BCA、CBA。

  • 何谓队列上溢?何为假溢出现象?有哪些解决假溢出问题的方法,并分别阐述其工作原理。

    答:队列上溢指在队列的顺序存储分配中,所有单元中已有元素,再进行插入操作时称为队列上溢。

    假溢出指在队列的顺序存储分配中,分配给队列的存储空间有存储单元未被占用,但按照操作规则而使进队的数据元素无法进队的现象。

    解决假溢出问题的方法是在队列的顺序存储分配中,分配给队列的存储空间可以循环使用,其进本原理是用表示队头和队尾指针与分配给队列的存储空间长度进行取模运算。即:

    入队操作:Q.rear=(Q.rear+1)%MSize

    出队操作:Q.front=(Q.front+1)%MSize

  • 队列可以用单循环链表来实现,故可以只设一个头指针或只设一个尾指针,请分析用哪种方案最合适。

    答:使用循环链表来表示队列,设置尾指针比较合适,因为入队操作可以直接在尾结点后进行插入操作,出队操作时可以根据尾指针很容易找到链表的头结点,入队出队操作的算法时间复杂度均为O(1)。若只设头指针,则出队操作的算法时间复杂度为O(1),入队操作的算法时间复杂度为O(n)。

  • 简述线性表、栈和队列的异同?

    答:栈和队列都是操作位置受限的线性表,即对插入和删除操作的位置加以限制。栈是仅允许在表的一端进行插入和删除操作的线性表,因而是后进先出表。队列是允许在表的一端进行插入,在表的另一端进行删除的线性表,因而是先进先出表。线性表可以在任何位置进行插入和删除操作。

  • 串是任意有限个   字符构成的序列
  • 串是一种特殊的线性表,其特殊性体现在    数据元素是一个字符
  • 两个串相等必有串长度相等且   串中各位置字符均对应相等  
  • 设有两个串p和q,求q在p中首次出现的位置的运算称着    模式匹配
  • 空串是    长度为0的串              

  • 一个串中   任意连续字符组成的子序列      称为该串的子串。

  • 设s=“abcd”,则执行语句s2=Substr(s,2,2)后,s2=  “bc”           

  • 空白串是  由一个或多个空格字符组成的串    ,其长度等于  其所包含的空格字符的个数    

数组 

  • 一维数组与线性表的区别是   前者长度固定,后者长度可变
  • 多维数组的数组元素之间的关系,是线性的
  • 设有数组A[8][10],每个元素占3个存储单元,存放该数组的存储单元数为   240
  • 设有数组A[8][10],每个元素占3个存储单元,首地址为SA,则元素[7][5]的起始地址是  SA+225
  • 设有一个n*n的对称矩阵,采用压缩存储,则存入内存的元素个数为  n*(n+1)/2
  • 设A是一个n*n的对称矩阵,压缩存储到一个一维数组B[0..n(n+1)/2-1]中,则下三角部分元素ai,j在B中的位置是  i(i-1)/2+j-1
  • 稀疏矩阵一般的压缩方法有两种,即   三元组和十字链表
  • 设有一个10*10的对称矩阵A,以行主次序进行压缩存储,每个元素占一个存储单元,a1,1的地址是1,则A8,5的起始地址是  33
  • 设数组A[50][80],其基地址为2000,每个元素占2个存储单元,以行序位主序顺序存储,回答下列问题:

       (1)该数据组由多少元素?

       (2)该数组占用多少存储单元?

       (3)数组元素a[30][30]的存储地址是多少?

      答:

         (1)该数组有:50*80=4000个元素

         (2)该数组占用4000*4=8000个存储单元

         (3)loc(30,30)=2000+(30*80+30)*2=2000+4860=6860

树和二叉树 

  • 深度为k的完全二叉树至少有  2^k-1       个结点,至多有 2^k-1    个结点。
  • 在一棵二叉树中,度为0的结点个数为n0,度为2的结点个数为n2,则有n0= n2+1   
  • 一棵二叉树第i层最多有  2^(i-1)    个结点,一棵有n个结点的满二叉树共有 2^k  -1   个结点,共有  2^k  -1   个叶结点
  • 具有n个结点的二叉树采用二叉链表存储结构,共有   n+1     个空指针域。
  • 树与二叉树的两个主要差别是    树中结点的最大度没有限制,二叉树结点的最大度限定为2   、 树的结点无左右之分,二叉树的的结点有左右之分  
  • 树中任一结点允许有  0个或多个孩子      个孩子结点,除根结点之外,其余结点有   1   个双亲结点。

图 

  • 在一个无向图中,所有顶点的度数之和等于所有边的  2  倍。
  • 有n个顶点的无向图最多有    n(n-1)/2        条边。
  • 具有n个顶点的强连通有向图至少有  n     条边。
  • 具有n个顶点的有向图最多有  n(n-1)     条边。
  • 一个图的  邻接矩阵    表示法是唯一的,而  邻接表     表示法是不唯一的。
  • 具有10个顶点的无向图,边的总数最多为  45    
  • 在有n个顶点的有向图中,每个顶点的度最大可达    n-1         
  • 已知一个有向图采用邻接矩阵表示,计算第i个顶点的入度的方法是    求第i列非0元素个数   
  • 已知一个有向图的邻接矩阵表示,删除所有从第i个结点出发的弧的方法是  将第i行对应的1置成0      
  • 对于n的顶点的无向图,采用邻接矩阵表示,求图中边的方法是  计算邻接矩阵中元素值为1的个数       ,判断任意两个顶点是否有边相连的方法是  判断对应邻接矩阵元素的值是否为1,再除以2        ,求任意顶点的度的方法是   求邻接矩阵中对应顶点所在行值为1 的元素个数      
  • 从占用的存储空间来看,对于稠密图和稀疏图,采用邻接矩阵和邻接表那个更好些?

    答:从占用存储空间看,稠密图采用邻接矩阵更好,稀疏图采用邻接表更好。
  • 用邻接矩阵表示图时,矩阵元素的个数与顶点个数是否相关?与边的条数是否相关?为什么?。

    答:用邻接矩阵表示图,矩阵元素的个数与图的顶点个数直接相关,与边的条数无关。因为假设定点个数为n,则邻接矩阵的大小为n^2。

排序 

  • 每次从无序子表中取出一个元素,把它插入到有序子表中恰当位置,此种排序方法叫做 插入    排序;若每次从无序子表中挑选出最小或最大元素,把它交换到有序表的一端,此种排序方法叫做 直接选择     排序。
  • 每次通过基准元素间接比较两个元素,不满足约定要求时就交换位置,该排序方法叫做 快速   排序;每次使两个相邻有序表合并成一个有序表的排序方法叫做  归并   排序。
  •   快速    排序方法采用二分法的思想,  堆    排序方法将数据的组织采用完全二叉树的结构。
  • 对n个元素的表进行直接选择排序,所需要的关键字的比较次数为   n(n-1)/2     
  • 在堆和快速排序中,若原始记录接近正序或反序,则选用  堆    ,若原始记录无序,则选用   快速        

  • 在插入和选择排序中,若初始数据基本正序,则选用 插入      ,若初始数据基本反序,则选用  选择    

  • 在堆排序、快速排序和归并排序中,若只从存储空间考虑,则应首先选取  堆排序   方法,其次选择  快速排序   方法,最后选择 归并排序  方法;若只从平均情况下排序最快考虑,则应选取  快速排序 方法;若只从最坏情况下排序最快并且要节省内存考虑,则应选取  堆排序      方法。

猜你喜欢

转载自blog.csdn.net/weixin_46601559/article/details/126848329