[记录] 考研408专业课复习

线性表课后习题 真题训练

1.

设计一个递归算法,删除不带头节点的单链表L中值为x的结点

void DEL_X_3(Linklist &L,ElemType x)
{
	LNode *p;//指向要删除的结点
	if(L==NULL)
		return;
	if(L->data==x)
	{
		p=L;
		L=L->next;
		free(p);
		DEL_X_3(L,x);//递归调用
	}
	else
		//如果L指向的值不是x,递归调用,继续往下寻找
	DEL_X_3(L->next,x);
}

递归工作栈深度为O(n) 时间复杂度为O(n)

2.

已知带表头结点的单链表,结点结构为
data link
假设该链表值给出了头指针list,在不改变链表的前提下,设计一个尽可能高效的算法,查找链表中倒数第k个位置上的结点,若查找成功,算法输出该节点data域的值,否则,只返回0
基本思想:尽可能高效的算法,就是遍历一遍即可以得到倒数第k个位置上的结点,倒数第k个就需要知道整个链表的结尾在哪里,所以定义了两个指针p,q,基本思想就是p在遍历到链表结尾时,q指向倒数第k个位置,所以p和q之间相差的距离为k,即当p指针移动到第k个结点时,q开始移动,刚开始p,q都指向第一个结点,即头结点的下一个位置
具体实现步骤:
1. count=0,p,q指向L表头的下一个结点
2.判空 如果p为空,如count=k,则查找成功,输出对应的data值,返回1,否则查找失败,返回0
3.如果count=k,即q此时需要开始走,q指向下一个结点,否则的话count=count+1,q不动
4.p指向下一个结点,转2判断是否已经到表尾

typedef int Elemtype;
typedef struct LNode{
    Elemtype data;
    struct LNode *link;//指向头结点
}LNode,*Linklist;
int search_k(Linklist list,int k)
{
    int count=0;
    LNode *p=list->list;//list->next?
    LNode *q=list->list;
    while(p!=NULL)//若p非空,即没有到表尾,结束条件就是p为空即到达表尾
    {
        if(count<k)//count<k 此时q不动 p移动
            count++;
        else q=q->next;//count=k时,q开始移动 p继续移动
        p=p->next;
    }
    if(count<k)//count<k 表示表长比k小,查找失败返回0
        return 0;
    else{//count=k,查找成功输出q所指的data,返回1
        prinf("%d",q->data);
        return 1;
    }
}

3.

假定采用带头结点的单链表保存单词,当两个单词有相同后缀时,可以共享相同的后缀存储空间,如,“ loading ”和“ being ”的存储映像如下图所示。

设 str1 和 str2 分别指向两个单词所在单链表的头结点,链表结点结构为 ,请设计一个时间上尽可能高效的算法,找出由 str1 和 str2 所指向两个链表共同后缀的起始位置(如图中字符 i 所在结点的位置 p )。要求:

1 )给出算法的基本设计思想。

2 )根据设计思想,采用 C 或 C++ 或 Java 语言描述算法,关键之处给出注释。

3 )说明你所设计算法的时间复杂度。

基本思想:分别遍历两个单词,得到分别的长短m,n,表尾对齐,如果m>=n,则str1先走走到m-n+1的位置,此时和另一个单词对齐,若m<n,则str2先走,走到n-m+1位置,与第一个单词对齐,之后两个指针同时移动,指向同一位置时停止,即为共同后缀的起点。

typedef struct Node{
    char data;
    struct Node *next;
}SNode;
int listlen(SNode *head)//求单词链表长度
{
    int len=0;
    while(head->next!=NULL)
    {
        len++;
        head=head->next;
    }
    return len;
}
SNode *find add(SNode *str1,SNode *str2)//查找共同后缀
{
    int m,n;
    m=listlen(str1);
    n=listlen(str2);
    for(p=str1;m>n;m--)
        p=p->next;
    for(q=str2;m<n;n--)
        q=q->next;
    while(p->next!=NULL && q->next!=NULL && p->next!=q->next)//循环到p的下一个指向=q的下一个指向时停止,这里其实有个疑问,参考书所给没有q->next!=NULL这一条件,但是我认为应该要保证两个链表下一个指向都不为NULL...大概是这样 不太确定
    {
        p=p->next;
        q=q->next;
    }
    return p->next;
}

时间复杂度为O(len1+len2)/O(max(len1,len2))

这里其实有个疑问,参考书在while中没有给q->next!=NULL这一条件,只有一个p->next!=NULL,但是我认为应该要保证两个链表下一个指向都不为NULL...大概是这样 不太确定,菜鸟求解答ww

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值