DS_LinkedList

1-1

在具有N个结点的单链表中,访问结点和增加结点的时间复杂度分别对应为O(1)和O(N)。

F


1-2

将N个数据按照从小到大顺序组织存放在一个单向链表中。如果采用二分查找,那么查找的平均时间复杂度是O(logN)。

F


1-3

若用链表来表示一个线性表,则表中元素的地址一定是连续的。

F


1-4

链表 - 存储结构

链表是一种随机存取的存储结构。

F


1-5

线性表L如果需要频繁地进行不同下标元素的插入、删除操作,此时选择顺序存储结构更好。

F


2-1

在具有N个结点的单链表中,实现下列哪个操作,其算法的时间复杂度是O(N)?

A.在地址为p的结点之后插入一个结点

B.删除开始结点

C.遍历链表和求链表的第i个结点

D.删除地址为p的结点的后继结点


2-2

将线性表La和Lb头尾连接,要求时间复杂度为O(1),且占用辅助空间尽量小。应该使用哪种结构?

A.单链表

B.单循环链表

C.带尾指针的单循环链表

D.带头结点的双循环链表


2-3

对于一个具有N个结点的单链表,在给定值为x的结点后插入一个新结点的时间复杂度为

A.O(1)

B.O(N/2)

C.O(N)

D.O(N2)


2-4

对于一非空的循环单链表,hp分别指向链表的头、尾结点,则有:

A.p->next == h

B.p->next == NULL

C.p == NULL

D.p == h


2-5

分数 2

作者 DS课程组

单位 浙江大学

将两个结点数都为N且都从小到大有序的单向链表合并成一个从小到大有序的单向链表,那么可能的最少比较次数是:

A.1

B.N

C.2N

D.NlogN


2-6

采用多项式的非零项链式存储表示法,如果两个多项式的非零项分别为N1​和N2​个,最高项指数分别为M1​和M2​,则实现两个多项式相乘的时间复杂度是:

A.O(N1​+N2​)

B.O(M1​+M2​)

C.O(N1​×N2​)

D.O(M1​×M2​)


2-7

已知表头元素为c的单链表在内存中的存储状态如下表所示:

f12dd9894c6f48b3a18718b53b04ec20.jpeg

 现将f存放于1014H处,并插入到单链表中,若f在逻辑上位于ae之间,则aef的“链接地址”依次

 

是:

A.1010H1014H1004H

B.1010H1004H1014H

C.1014H1010H1004H

D.1014H1004H1010H


2-8

已知指针ha和hb分别是两个单链表的头指针,下列算法将这两个链表首尾相连在一起,并形成一个循环链表(即ha的最后一个结点链接hb的第一个结点,hb的最后一个结点指向ha),返回ha作为该循环链表的头指针。请将该算法补充完整。

typedef struct node{
ElemType data;
    struct node *next;
}LNode;
LNode *merge(LNode *ha, LNode *hb) {
LNode *p=ha;
     if (ha==NULL || hb==NULL) {
cout<<”one or two link lists are empty!”<<endl;
          return NULL;
     }
     while ( p->next!=NULL )
           p=p->next;
     p->next=hb;
     while ( p->next!=NULL )
           p=p->next;
           __________
}

A.ha=p->next; return ha;

B.p->next=ha; return ha;

C.ha=p->next; return p;

D.p->next=ha; return p;


2-9

假设某个带头结点的单链表的头指针为head,则判定该表为空表的条件是( )

A.head==NULL

B.head->next==NULL

C.head!=NULL

D.head->next==head


2-10

单链表 - 时间复杂度

在包含 n 个数据元素的单链表中,▁▁▁▁▁ 的时间复杂度不为 O(n)。

A.访问第 i(1≤i≤n) 个数据元素

B.在位序 i(1≤i≤n+1) 处插入一个新结点

C.删除位序 i(1≤i≤n) 处的结点

D.将 n 个元素按升序排序


5-1

单链表逆转

分数 5

作者 DS课程组

单位 浙江大学

下列代码的功能是返回带头结点的单链表L的逆转链表。

List Reverse( List L )
{
    Position Old_head, New_head, Temp;
    New_head = NULL;
    Old_head = L->Next;

    while ( Old_head )  {
        Temp = Old_head->Next;
        
        ______________________________;
        New_head = Old_head;  
        Old_head = Temp; 
    }
    
______________________________;
    return L;
}

Old_head->Next = New_head;

L->Next = New_head; 


6-1 单链表分段逆转

给定一个带头结点的单链表和一个整数K,要求你将链表中的每K个结点做一次逆转。例如给定单链表 1→2→3→4→5→6 和 K=3,你需要将链表改造成 3→2→1→6→5→4;如果 K=4,则应该得到 4→3→2→1→5→6。

函数接口定义:

void K_Reverse( List L, int K ); 

其中List结构定义如下:

typedef struct Node *PtrToNode;
struct Node {
    ElementType Data; /* 存储结点数据 */
    PtrToNode   Next; /* 指向下一个结点的指针 */
};
typedef PtrToNode List; /* 定义单链表类型 */

L是给定的带头结点的单链表,K是每段的长度。函数K_Reverse应将L中的结点按要求分段逆转。

裁判测试程序样例:

#include <stdio.h>
#include <stdlib.h>

typedef int ElementType;

typedef struct Node *PtrToNode;
struct Node {
    ElementType Data; /* 存储结点数据 */
    PtrToNode   Next; /* 指向下一个结点的指针 */
};
typedef PtrToNode List; /* 定义单链表类型 */

List ReadInput(); /* 裁判实现,细节不表 */
void PrintList( List L ); /* 裁判实现,细节不表 */
void K_Reverse( List L, int K );

int main()
{
    List L;
    int K;

    L = ReadInput();
    scanf("%d", &K);
    K_Reverse( L, K );
    PrintList( L );

    return 0;
}

/* 你的代码将被嵌在这里 */

输入样例:

6
1 2 3 4 5 6
4

输出样例:

4 3 2 1 5 6
void K_Reverse( List L, int K )
{
    int count = 0,cnt = 1;
    List New, Old, Tag, p = L->Next, q = L, Last;
    while(p!=NULL)
    {
        p = p->Next;
        count++;
    }
    for(int i = 0;i < count/K;i++)
    {
        cnt = 1;
        New = q->Next;
        Old = New->Next;
        Last = New;//Last指向每一轮逆转的第一个结点,逆转后就变成了最后一个结点
        while(cnt < K)
        {
            Tag = Old->Next;
            Old->Next = New;
            New = Old;
            Old = Tag;
            cnt++;
        }
        q->Next = New;
        Last->Next = Old;
        q = Last;
    }
}

 


6-2 共享后缀的链表

有一种存储英文单词的方法,是把单词的所有字母串在一个单链表上。为了节省一点空间,如果有两个单词有同样的后缀,就让它们共享这个后缀。下图给出了单词“loading”和“being”的存储形式。本题要求你找出两个链表的公共后缀。

04263336bd2bfa904b107f4e8aea74b8.jpeg

函数接口定义:

PtrToNode Suffix( List L1, List L2 ); 

其中List结构定义如下:

 

typedef struct Node *PtrToNode; struct Node { ElementType Data; /* 存储结点数据 */ PtrToNode Next; /* 指向下一个结点的指针 */ }; typedef PtrToNode List; /* 定义单链表类型 */

L1L2都是给定的带头结点的单链表。函数Suffix应返回L1L2的公共后缀的起点位置。

裁判测试程序样例:

#include <stdio.h>
#include <stdlib.h>

typedef char ElementType;

typedef struct Node *PtrToNode;
struct Node {
    ElementType Data; /* 存储结点数据 */
    PtrToNode   Next; /* 指向下一个结点的指针 */
};
typedef PtrToNode List; /* 定义单链表类型 */

void ReadInput( List L1, List L2 ); /* 裁判实现,细节不表 */
void PrintSublist( PtrToNode StartP ); /* 裁判实现,细节不表 */
PtrToNode Suffix( List L1, List L2 );

int main()
{
    List L1, L2;
    PtrToNode P;

    L1 = (List)malloc(sizeof(struct Node));
    L2 = (List)malloc(sizeof(struct Node));
    L1->Next = L2->Next = NULL;
    ReadInput( L1, L2 );
    P = Suffix( L1, L2 );
    PrintSublist( P );

    return 0;
}

/* 你的代码将被嵌在这里 */

输入样例:

如图存储的链表

8428838f97785b8e1f684c97348d69bd.jpeg

输出样例:

ing

 

#include<math.h>
PtrToNode Suffix( List L1, List L2 )
{
    PtrToNode p = L1, q = L2;
    int len1 = 0, len2 = 0;
    while(p != NULL)
    {
        p = p->Next;
        len1++;
    }
    while(q != NULL)
    {
        q = q->Next;
        len2++;
    }
    if(len1 > len2)
        p = L1,q = L2;
    else
        p = L2,q = L1;
    for(int i = 0;i < abs(len1-len2);i++)
    {
        p = p->Next;
    }
    for(int i = 0;i < 5;i++)
    {
        int j = i;
    }
    while(p->Next != q->Next)
    {
        p = p->Next;
        q = q->Next;
    }
   return p->Next;
}

7-1 喊山

喊山,是人双手围在嘴边成喇叭状,对着远方高山发出“喂—喂喂—喂喂喂……”的呼唤。呼唤声通过空气的传递,回荡于深谷之间,传送到人们耳中,发出约定俗成的“讯号”,达到声讯传递交流的目的。原来它是彝族先民用来求援呼救的“讯号”,慢慢地人们在生活实践中发现了它的实用价值,便把它作为一种交流工具世代传袭使用。(图文摘自:http://news.xrxxw.com/newsshow-8018.html)

 

一个山头呼喊的声音可以被临近的山头同时听到。题目假设每个山头最多有两个能听到它的临近山头。给定任意一个发出原始信号的山头,本题请你找出这个信号最远能传达到的地方。

输入格式:

输入第一行给出3个正整数nmk,其中n(≤10000)是总的山头数(于是假设每个山头从1到n编号)。接下来的m行,每行给出2个不超过n的正整数,数字间用空格分开,分别代表可以听到彼此的两个山头的编号。这里保证每一对山头只被输入一次,不会有重复的关系输入。最后一行给出k(≤10)个不超过n的正整数,数字间用空格分开,代表需要查询的山头的编号。

输出格式:

依次对于输入中的每个被查询的山头,在一行中输出其发出的呼喊能够连锁传达到的最远的那个山头。注意:被输出的首先必须是被查询的个山头能连锁传到的。若这样的山头不只一个,则输出编号最小的那个。若此山头的呼喊无法传到任何其他山头,则输出0。

输入样例:

7 5 4
1 2
2 3
3 1
4 5
5 6
1 4 5 7

输出样例:

2
6
4
0
#include <iostream>
#include <bits/stdc++.h>
using namespace std;

struct shan
{
	int l;
	int	no;
};

const int N = 10001;
vector<int>v[N];
int bj[N];
queue<shan>q;

void clear(queue<shan> &p)
{
	queue<shan> empty;
	swap(empty, p);
}

int bfs(int x)
{
	//clear(q);
	memset(bj, 0, sizeof(bj));
	shan s;
	int lc = 0, No = x;
	s.l = 0;
	s.no = x;
	q.push(s);
	bj[x] = 1;
	while (1)
	{
		if (q.empty())
			break;
		shan s1 = q.front();
		if (lc == s1.l)
			No = min(No, s1.no);
		else if (lc < s1.l)
		{
			lc = s1.l;
			No = s1.no;
		}
		for (int i = 0; i < v[s1.no].size(); i++)
		{
			if (bj[v[s1.no][i]] == 0)
			{
				bj[v[s1.no][i]] = 1;
				s.l = s1.l + 1;
				s.no = v[s1.no][i];
				q.push(s);
			}
		}
		q.pop();
	}
	if (lc == 0)
		return 0;
	else
		return No;
}

int main()
{
	int n, m, k;
	cin >> n >> m >> k;
	int m1, m2;
	memset(bj, 0, sizeof(bj));
	for (int i = 0; i < m; i++)
	{
		cin >> m1 >> m2;
		v[m1].push_back(m2);
		v[m2].push_back(m1);//建图
	}
	for (int i = 1; i <= k; i++)
	{
		int x;
		cin >> x;
		cout << bfs(x) << endl;
	}
	return 0;
}

 

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

102101222_张凯权

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值