问题: 假设带有头节点的单链表,节点结构如下图:
假设该链表只给出了头指针list,在不改变链表的前提下,请设计一个尽可能高效的算法,查找链表中倒数第k个位置上的节点(k为正整数)。若查找成功,算法输出该节点数据域的值,并返回1;否则返回0;要求如下:
- 描述算法的基本设计思想。
- 描述算法的详细实现步骤。
- 根据设计思想和实现步骤,采用程序设计语言描述算法。
解答:
(1) 算法的基本思想:
定义两个指针p个q,初始时均指向头节点的下一个节点。p指针沿着链表移动,当p指针移动到第k个节点时,q指针域p指针同步移动;当p指针移动到链表表尾节点时,q指针所指向的节点即为倒数dik个节点。
(2)算法的详细步骤如下
① 令count=0,p和q指向链表的第一个节点。
②若p为空,则转向⑤执行。
③若count等于k,则q指向下一个节点;否则令count++
④令p指向下一个节点,转向②执行。
⑤若count等于k,则查找成功,输出节点的数据域的值,并返回1;否则,查找失败,返回0
(3)算法代码实现:
//
// Created by Yuecaizheng on 2020/12/3.
//
typedef struct LNode { //定义节点
int data;
LNode *link;
} *LinkList; //定义节点指针变量
int SearchNode(LinkList list, int k) //查找节点
{
LinkList p, q; //定义两个指针变量p个q
int count = 0; //定义计数器变量并赋初值为0
p = q = list->link; //p和q指向链表的第一个节点
while (p != NULL) {
if (count < k) //若p未移动到第k个节点
count++; //计数器加1
else
q = q->link;
p = p->link; //p移动到下一个节点
}
if (count < k) //如果满足小于k
return 0; //返回0
else {
printf("倒数第%d个节点的元素值为%d\n", k, q->data); //输出倒数第k个节点的元素值
return 1; //返回1
}
}