单链表第二十一题(寻找倒数第k个元素)

 21.已知一个带有表头节点的单链表,结点结构为

data

link

假设该链表只给出了头指针。

在不改变链表的前提下,请设计一个尽可能高效的算法,

查找链表中倒数第k个位置上的结点(k为正整数)。

若查找成功,算法输出该结点的data域的值,并返回1;

否则,只返回0,要求:

1)描述算法的基本设计思想。

2)描述算法的详细实现步骤。

3)根据设计思想和实现步骤,采用程序设计语言描述算法(使用C、C++或java语言实现),

    关键之处请给出简要注释。

/*

    有一个带头节点的单链表,设计一个函数找到指定的倒数第K个节点,

    输出节点值,并返回1,否则返回0,前提不能改变链表,尽可能高效

分析:

     我们可以先统计出总共的节点数count,那么该节点的顺序数num=count-k+1,

当然如果K>count,直接返回0,时间复杂度为0(n),这里还有另一种更加便捷的方法,

只需对链表遍历一次,我们设立两个指针,最开始均指向首节点,然后让q先移动k个节点,

之后p,q同步移动,当q为NULL时,p所在的位置便是倒数第k个节点的位置

*/

#define_CRT_SECURE_NO_WARNINGS

#include<stdio.h>

#include"linkStruct.h"//通过自创建头文件引入结构体,ctrl+鼠标左键点击即可查看

int  findTheReciprocalk(Link *h,int  k){//这是第一种解法

    Link   *p=h->next;

    int  count=0;num;

      while(p){//统计元素个数

                  count++;

                 p=p->next;    

       } 

       p=h->next;

       if(k>count){

             return   0;

           }

          else{

                 num=count-k+1;

                  while(--num){//这里要用--num,如果用num--,会导致p为下一个元素,注意

                         p=p->next;

                        }

                 printf("%d",p->data);

                 return  1;

                }

}     

int  findTheReciprocalK2(Link  *h,int k){//这是第二种解法

          Link  *p=h->next,*q=h->next;

          int  count=k;

           while(count--){

                     if(q=NULL){

                                   printf("倒数第%d个节点不存在",k);

                                    return  0;

                          }

                           q=q->next;

             }

              while(q!=NULL){

                     p=p->next;

                      q=q->next;

               }

              printf("倒数第%d个节点值为:%d",k,p->data);

              return   1;

}           

int  main(){

          int  k;

          Link  *head;

          Link*createLink(int);

          head=createLink(0);

          printf("请输入要查倒数第几个数:k=");

           scanf("%d",&k);

           //findTheReciprocalk(head,k);

           findTheReciprocalk2(head,k);

           return    0;

}                                                                                                                                                                                                                                                                                                                                                                                                                                                    

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值