线性表课后习题 真题训练
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