数据结构(二)线性表

哈哈,有木有感觉我复习的很快!(希望以后的几张也能这么快)
对,我提一下,我的复习方法是先看网易云课堂上小甲鱼的数据结构与算法这门课边听便在书上做笔记,然后去做对应的习题。


1.选择题

(1)顺序表中第一个元素的存储地址是100,每个元素的长度为2,则第5个元素的地址是( B )。

A.110 B.108 C.100 D.120

解释:顺序表中的数据连续存储,所以第5个元素的地址为:100+2*4=108。

(2)在n个结点的顺序表中,算法的时间复杂度是O(1)的操作是( A )。

A.访问第i个结点(1≤i≤n)和求第i个结点的直接前驱(2≤i≤n)
B.在第i个结点后插入一个新结点(1≤i≤n)
C.删除第i个结点(1≤i≤n)
D.将n个结点从小到大排序

解释:在顺序表中插入一个结点的时间复杂度都是O(n),排序的时间复杂度为O(n2)或O(nlog2n)。顺序表是一种随机存取结构,访问第i个结点和求第i个结点的直接前驱都可以直接通过数组的下标直接定位,时间复杂度是O(1)。

(3)线性表若采用链式存储结构时,要求内存中可用存储单元的地址( D )。

A.必须是连续的 B.部分地址必须是连续的
C.一定是不连续的 D.连续或不连续都可以

解释:若采用链式存储结构,内存中可用存储单元的地址是不需要连续的,因为有每个元素都是由数据域和指针域构成的,而指针域就可以告诉后继元素的位置。

(4)线性表L在( B )情况下适用于使用链式结构实现。

A.需经常修改L中的结点值 B.需不断对L进行删除插入
C.L中含有大量的结点 D.L中结点结构复杂

解释:链表最大的优点在于插入和删除时不需要移动数据,直接修改指针即可。

(5)将两个各有n个元素的有序表归并成一个有序表,其最少的比较次数是( A )。

A.n B.2n-1 C.2n D.n-1

解释:当第一个有序表中所有的元素都小于(或大于)第二个表中的元素,只需要用第二个表中的第一个元素依次与第一个表的元素比较,总计比较n次。

(6)在一个长度为n的顺序表中,在第i个元素(1≤i≤n+1)之前插入一个新元素时须向后移动( B )个元素。

A.n-i B.n-i+1 C.n-i-1 D.I

解释:比如说现在有 1 2 3 4 5,共计5(为题中的n)个元素,要在3和4(为题中的i)之间插入x元素,需要把5-4+1个元素后移

(7) 创建一个包括n个结点的有序单链表的时间复杂度是( C )。

A.O(1) B.O(n) C.O(n2) D.O(nlog2n)

解释:单链表创建的时间复杂度是O(n),而要建立一个有序的单链表,则每生成一个新结点时需要和已有的结点进行比较,确定合适的插入位置,所以时间复杂度是O(n2)。

(8) 在单链表中,要将s所指结点插入到p所指结点之后,其语句应为( D )。

A.s->next=p+1; p->next=s;
B.(*p).next=s; (*s).next=(*p).next;
C.s->next=p->next; p->next=s->next;
D.s->next=p->next; p->next=s;

解释:这个题可以自己画图来解决。。如果不懂,去网上搜搜,哈哈,考试快了,不然我就自己画图讲了。【加油哈!】

(9) 在双向链表存储结构中,删除p所指的结点时须修改指针( A )。

A.p->next->prior=p->prior; p->prior->next=p->next;
B.p->next=p->next->next; p->next->prior=p;
C.p->prior->next=p; p->prior=p->prior->prior;
D.p->prior=p->next->next; p->next=p->prior->prior;

解释:如题(8),大家加油!!

(10) 在双向循环链表中,在p指针所指的结点后插入q所指向的新结点,其修改指针的操作是( C)。

A.p->next=q; q->prior=p; p->next->prior=q; q->next=q;
B.p->next=q; p->next->prior=q; q->prior=p; q->next=p->next;
C.q->prior=p; q->next=p->next; p->next->prior=q; p->next=q;

解释:现在,不得不向各位大佬低头,这个 p->next->prior=q是啥意思呀??【一脸懵逼】

哈哈,懂了!

如图:在p和r指针所指的结点中间要插入q所指向的新结点【prior|p|next】>–【prior|r|next】, p->next即为r指针,p->next->prior=q就是r指针的prior指向q。

2.算法设计题

(1)已知两个链表A和B分别表示两个集合,其元素递增排列。请设计算法求出A与B的交集,并存放于A链表中。

[题目分析]
只有同时出现在两集合中的元素才出现在结果表中,合并后的新表使用头指针Lc指向。pa和pb分别是链表La和Lb的工作指针,初始化为相应链表的第一个结点,从第一个结点开始进行比较,当两个链表La和Lb均为到达表尾结点时,如果两个表中相等的元素时,摘取La表中的元素,删除Lb表中的元素;如果其中一个表中的元素较小时,删除此表中较小的元素,此表的工作指针后移。当链表La和Lb有一个到达表尾结点,为空时,依次删除另一个非空表中的所有元素。

void Mix(LinkList& La, LinkList& Lb, LinkList& Lc){
      pa=La->next;
      pb=Lb->next; //pa和pb分别是链表La和Lb的工作指针,初始化为相应链表的第一个结点
      Lc=pc=La; //用La的头结点作为Lc的头结点
  while(pa&&pb){
      if(pa->data==pb->data)//交集并入结果表中。
      { 
       pc->next=pa;
       pc=pa;
       pa=pa->next;
       u=pb;
       pb=pb->next;
       delete u;
    }
      else if(pa->data < pb->data) 
        {
         u=pa;
         pa=pa->next; 
         delete u;
      }
      else
        {
        u=pb; 
        pb=pb->next;
        delete u;
       }
  }
  while(pa) 
    {
        u=pa; pa=pa->next; delete u;
  }// 释放结点空间
  while(pb) 
    {
        u=pb; pb=pb->next; delete u;
  }//释放结点空间

  pc->next=null;//置链表尾标记。

  delete Lb;  //释放Lb的头结点
}

(2)设计一个算法,通过一趟遍历在单链表中确定值最大的结点。

[题目分析]
假定第一个结点中数据具有最大值,依次与下一个元素比较,若其小于下一个元素,则设其下一个元素为最大值,反复进行比较,直到遍历完该链表。

ElemType Max (LinkList L ){
    if(L->next==NULL) 
        return NULL;

    pmax=L->next; //假定第一个结点中数据具有最大值

    p=L->next->next;

    while(p != NULL )//如果下一个结点存在
        {
        if(p->data > pmax->data) 
        pmax=p;//如果p的值大于pmax的值,则重新赋值
        p=p->next;//遍历链表
    }
    return pmax->data;

(3)设计一个算法,通过遍历一趟,将链表中所有结点的链接方向逆转,仍利用原表的存储空间。

[题目分析]
从首元结点开始,逐个地把链表L的当前结点p插入新的链表头部。

void  inverse(LinkList &L) 
{// 逆置带头结点的单链表 L
    p=L->next;  
    L->next=NULL;
    while (p) {
        q=p->next;    // q指向*p的后继
        p->next=L->next;
        L->next=p;       // *p插入在头结点之后
        p = q;
    }
}

(4)(本题为选做题,可不做)
已知长度为n的线性表A采用顺序存储结构,请写一时间复杂度为O(n)、空间复杂度为O(1)的算法,该算法删除线性表中所有值为item的数据元素。

[题目分析]
在顺序存储的线性表上删除元素,通常要涉及到一系列元素的移动(删第i个元素,第i+1至第n个元素要依次前移)。本题要求删除线性表中所有值为item的数据元素,并未要求元素间的相对位置不变。因此可以考虑设头尾两个指针(i=1,j=n),从两端向中间移动,凡遇到值item的数据元素时,直接将右端元素左移至值为item的数据元素位置。

void  Delete(ElemType A[ ],int  n)//A是有n个元素的一维数组,本算法删除A中所有值为item的元素。

{
    i=1;j=n;//设置数组低、高端指针(下标)。
    while(i<j)
     {
       while(i<j && A[i]!=item)
       i++;         //若值不为item,左移指针。
        if(i<j)
        {
         while(i<j && A[j]==item)
            j--;
          }//若右端元素为item,指针左移
    if(i<j)
    {
      A[i++]=A[j--];
      }
}

这里写图片描述

大家考试,也加油呀!!!
  • 3
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值