作业6-改进的单链表及其应用

作业6-改进的单链表及其应用

2-1
对于一非空的循环单链表,
h和p分别指向链表的头、尾结点,则有:(A)
A.p->next == h
B.p->next == null
C.p == null
D.p == h

2-2
在双向循环链表结点p之后插入s的语句是:(D)
A.p->next=s; s->prior=p; p->next->prior=s ; s->next=p->next;
B.p->next->prior=s; p->next=s; s->prior=p; s->next=p->next;
C.s->prior=p; s->next=p->next; p->next=s; p->next->prior=s;
D.s->prior=p; s->next=p->next; p->next->prior=s; p->next=s;

2-3
在双向链表存储结构中,删除p所指的结点,相应语句为:©
A.p->prior=p->prior->prior; p->prior->next=p;
B.p->next->prior=p; p->next=p->next->next;
C.p->prior->next=p->next; p->next->prior=p->prior;
D.p->next=p->prior->prior; p->prior=p->next->next;

2-4
某线性表中最常用的操作是在最后一个元素之后
插入一个元素和删除第一个元素,
则采用什么存储方式最节省运算时间?(B)
A.单链表
B.仅有尾指针的单循环链表
C.仅有头指针的单循环链表
D.双链表
[解析]对C,若要在最后插入一个元素,那么只有头指针你还得遍历到最后
对D,双链表但不是循环的,那么在最后位置插入和头指针的情况一样

2-5
若某表最常用的操作是在最后一个结点之后
插入一个结点或删除最后一个结点。
则采用哪种存储方式最节省运算时间?()
A.单链表
B.双链表
C.单循环链表
D.带头结点的双循环链表
[解析]ABC在最后插入节点都需要遍历一遍链表

2-6
将线性表La和Lb头尾连接,要求时间复杂度为O(1),
且占用辅助空间尽量小。应该使用哪种结构?(D)
A.单链表
B.单循环链表
C.带尾指针的单循环链表
D.带头结点的双循环链表
[解析]AB需要遍历链表,C只需要修改两个尾指针的内容
并且释放掉第二个链表的头指针即可
D时间是O(1),但是空间利用率不如C

2-7
(neuDS)在链表中若经常要删除表中最后一个结点或在
最后一个结点之后插入一个新结点,则宜采用()存储方式。©
A.顺序表
B.用头指针标识的循环单链表
C.用尾指针标识的循环单链表
D.双向链表
[解析]我感觉C也好像不太好,在删除最后一个节点的时候
还是需要遍历链表

2-8
非空的循环单链表head的尾结点(由p所指向)满足()。©
A.p->next == NULL
B.p == NULL
C.p->next == head
D.p == head

2-9
在循环双链表的p所指结点之前插入s所指结点的操作是()。(D)
A.p->prior = s; s->next = p; p->prior->next = s; s->prior = p->prior;
B.p->prior = s; p->prior->next = s; s->next = p; s->prior = p->prior;
C.s->next = p; s->prior = p->prior; p->prior = s; p->right->next = s;
D.s->next = p; s->prior = p->prior; p->prior->next = s; p->prior = s;

2-10
若某表最常用的操作是在最后一个结点之后插入一个结点或删除最后一个结点,
则采用()存储方式最节省运算时间。(D)
A.单链表
B.给出表头指针的单循环链表
C.双链表
D.带表头附加结点的双循环链表

2-11
某线性表最常用的操作是在最后一个结点之后
插入一个结点或删除第一个结点,故采用()存储方式最节省运算时间。(D)
A.单链表
B.仅有头结点的单循环链表
C.双链表
D.仅有尾指针的单循环链表

2-12
在一个长度为n(n>1)的单链表上,设有头和尾两个指针,
执行()操作与链表的长度有关。(B)
A.删除单链表中的第一个元素
B.删除单链表中的最后一个元素
C.在单链表第一个元素前插入一个新元素
D.在单链表最后一个元素后插入一个新元素
[解析]删除最后一个元素需要知道前一个元素的地址

2-13
如果对线性表的运算只有4种,即删除第一个元素,删除最后一个元素,
在第一个元素前面插入新元素,
在最后一个元素的后面插入新元素,则最好使用()。©
A.只有表尾指针没有表头指针的循环单链表
B.只有表尾指针没有表头指针的非循环双链表
C.只有表头指针没有表尾指针的循环双链表
D.既有表头指针也有表尾指针的循环单链表
[解析]主要还是删除最后一个节点遇到的问题,需要知道前一个节点的地址

2-14
如果对线性表的运算只有2种,即删除第一个元素,
在最后一个元素的后面插入新元素,则最好使用()。(B)
A.只有表头指针没有表尾指针的循环单链表
B.只有表尾指针没有表头指针的循环单链表
C.非循环双链表
D.循环双链表

2-15
在双向循环链表中,在p所指的结点之后插入s指针所指的结点,其操作是()。(D)
A.p->next = s; s->prior = p; (p->next)->prior = s; s->next = p->next;
B.s->prior = p; s->next = p->next; p->next = s; p->next->prior = s;
C.p->next = s; p->next->prior = s; s->prior = p; s->next = p->next;
D.s->prior = p; s->next = p->next; p->next->prior = s; p->next = s;

2-16
带表头附加结点的双向循环链表为空的判断条件是头指针L满足条件()。(D)
A.L= =NULL
B.L->right= =NULL
C.L->left = =NULL
D.L->right= =L

2-17
循环链表的主要优点是()。(D)
A.不再需要头指针了
B.已知某个结点的位置后,能够很容易找到它的直接前驱
C.在进行插入、删除运算时,能更好的保证链表不断开
D.从表中的任意结点出发都能扫描到整个链表
[解析]优点在遍历的时候体现

2-18

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

typedef struct node{
ElemType data;
struct node *next;
}LNode;
LNode *merge(LNode *ha, LNode *hb) {
LNode *p=ha;
if (haNULL || hbNULL) {
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-19

设有一个双向循环链表,每个结点中除有left、data和right三个域外,
还增设了一个访问频度域freq,freq 的初值为零。每当链表进行一次查找操作后,
被访问结点的频度域值便增1,同时调整链表中结点的次序,
使链表按结点频度值非递增有序的次序排列。下列算法是符合上述要求的查找算法,
请将该算法补充完整。©

typedef struct Node{
ElemType data;
struct Node *left;
struct Node *right;
intfreq;
} DNode;
DNode *locate_DList(DNode *&L, ElemType x)
{ //在表L中查找元素x,查找成功则调整结点频度域值及结点位置,并返回结点地址;
//查找不成功则返回NULL
DNode *p=L, *q;
if (LNULL) return NULL;
while (p->data!=x && p->right!=L) p=p->right;
if (p->data!=x) return NULL;
p->freq++;
q=p->left;
while (q!=L && q->freq<=p->freq) q=q->left; //查找插入位置
if (q
L && q->freq<=p->freq) { //需将p结点插在头结点L前
//将p结点先从链表中摘下来
p->left->right=p->right;
p->right->left=p->left;
//将p结点插在L结点前
p->right=L;
p->left=L->left;
L->left->right=p;
L->left=p;
L=p;
}
else if (q!=p->left ) { //若q不是p的前驱,则需调整结点位置,将p结点插在q结点后
//将p结点先从链表中摘下来
p->left->right=p->right;
p->right->left=p->left;
______________ //将p结点插在q结点后
}
return p;
}

A.p->left=q; p->right=q->right;
B.p->left=q; q->right=p;
C.p->left=q; p->right=q->right; q->right->left=p; q->right=p;
D.p->left=q; q->right=p; p->right=q->right; q->right->left=p;

2-20
与单链表相比,双链表的优点之一是()。(D)
A.插入、删除操作更加简单
B.可随机访问
C.可以省略表头指针或表尾指针
D.顺序访问相邻结点更加灵活
[解析]不太理解顺序是啥意思,但是访问一个节点的相邻节点确实更方便了

2-21
采用多项式的非零项链式存储表示法,如果两个多项式的非零项分别为N​1​​和N​2​​个,
最高项指数分别为M​1​​和M​2​​,则实现两个多项式相乘的时间复杂度是:(A)
A.O(N​1​​×N​2​​)
B.O(M​1​​×M​2​​)
C.O(N​1​​+N​2​​)
D.O(M​1​​+M​2​​)

6-1 带头结点的单链表就地逆置 (9)
/* 请在这里填写答案 */
//这是把元素提出来,一个一个重新逆序插入链表L中
//不过要注意插入之前L->next要赋NULL,否则链表尾结点的next不为空
//输出会死循环好像
void ListReverse_L(LinkList &L)
{
	LNode *temp = NULL;
	LNode *p = L->next;
    L->next = NULL;
	while (p)
	{
		temp = p;
		p = p->next;
		temp->next = L->next;
		L->next = temp;
	}
	return ;
}

前一个题越写越乱,就放弃了

7-24 求链式线性表的倒数第K项 (20)

#include <iostream>
#include <malloc.h>
using namespace std;
#define OVERFLOW -2

typedef int ElemType;
typedef struct DuLNode
{
	struct DuLNode* left, *right;
	ElemType data;
}DuLNode, *DuList;

void initList_DuL(DuList &L)
{
	L = (DuLNode*)malloc(sizeof(DuLNode));
	if (L == NULL) exit(OVERFLOW);
	L->left = L;
	L->right = L;
}
void AddNode(DuList &L)
{
	DuLNode *p = L;
	int num;
	while (cin >> num)
	{
		if (num < 0) break;
		DuLNode *temp_node = (DuLNode*)malloc(sizeof(DuLNode));
		if (temp_node == NULL) exit(OVERFLOW);
		temp_node->data = num;
		
		temp_node->left = p;
		temp_node->right = p->right;
		p->right = temp_node;
		L->left = temp_node;
		p = temp_node;
	}
}
int get_elem_in_k(DuList L, int k)
{
	DuLNode *p = L;
	for (int i = 0; i < k; i++)
	{
		if (p == L) return -1;
		p = p->left;
	}
	return p->data;
}
int main()
{
	int k;
	DuList L;
	initList_DuL(L);
	cin >> k;
	AddNode(L);
	int num = get_elem_in_k(L, k);
	if (num == -1) cout << "NULL" << endl;
	else cout << num;
	system("pause");
	return 0;
}

  • 1
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值