题目
已知一个带有表头结点的单链表,结点结构为
data | link |
---|
假设该链表只给出了头指针list。在不改变链表的前提下,请设计一个尽可能高效的算法,查找链表中倒数第k个位置上的结点(k为正整数)。若查找成功,算法输出该结点的data值,并返回1;否则,只返回0。要求:
题解
分析
1. 带头结点的单链表
首先,链表是一种线性表,在每一个节点里存到下一个节点的指针。
其次,区分 头结点和头指针
-
头结点:有时,在链表的第一个结点之前会额外增设一个结点,结点的数据域一般不存放数据(有些情况下也可以存放链表的长度等信息),此结点被称为头结点。
若头结点的指针域为空(NULL),表明链表是空表。头结点对于链表来说,不是必须的,在处理某些问题时,给链表添加头结点会使问题变得简单。 -
头指针:永远指向链表中第一个结点的位置(如果链表有头结点,头指针指向头结点;否则,头指针指向首元结点)。
2. 结点结构
data为数据域,存放数据元素。link为指针域,存放后继结点的地址
单链表下,结点类型代码:
typedef struct LNode{
ElemType data;
struct LNode *next;
}LNode, *LinkList;
3. 头指针list
题目:已存在一个单链表,但只知道该链表的头指针,其余未知。
4. 查找倒数第k个结点
此时,可使用的信息只有:头指针list和位置k
算法:设置两个头指针,其中一个先移动k-1,然后同时移动到最后,剩下的一个指针就是倒数第k个位置
代码
typedef struct LNode{
ElemType data;
struct LNode *next;
}LNode, *LinkList;
int search(LinkList L, ElemType k){
LNode *p = L->next;
LNode *q = L->next;
while(p->next!=NULL){
if(k>1){
p = p->next;
k--;
}
p = p->next;
q = q->next;
}
//此时,q是倒数第k个结点的指针
//查找失败的情况:k>链表长度,即p指针移动到链表末尾,k值没有减完
if(k>1){
return 0;
}
cout<<q->data;
return 1;
}