zoukankan      html  css  js  c++  java
  • 单链表倒数第K个节点的查找和显示

    最近在学回顾之前学到的知识,正好碰到了关于链表查找的一道面试题,在此贴出来,与小伙伴们共同交流~

    在刚看到题目,其实很容易就想到一个方法,就是先求链表的长度(length),然后去超找第length-k+1个节点的值,再进行查找,先贴代码如下。

    #include <stdio.h>
    #include <malloc.h>
    /*链表节点结构*/
    typedef struct node{
        int data;
        struct node * pNext;
    }NODE,*PNODE;
    /*函数声明*/
    PNODE create_list();
    void show_list(PNODE p);
    void show_list_list(PNODE p);
    int serch_k(PNODE p,int k);
    /*主函数*/
    int main(){
        int k;
        int len;
        PNODE pHead=NULL;
        pHead=create_list();
        show_list(pHead);
        len=show_list_length(pHead);
        printf("
    %d",len);
        k=serch_k(pHead,2);//查找倒数第K个值
        printf("
    %d",k);
        return 0;
    }
    /*生产链表*/
    PNODE create_list(void){
        int len;
        int val;
        int i;
        scanf("%d
    ",&len);
        PNODE pHead=(PNODE)malloc(sizeof(NODE));
        if(pHead==NULL){
            printf("error");
        }
        PNODE pTail=pHead;
        pTail->pNext=NULL;
        for(i=0;i<len;i++){
            scanf("%d",&val);
            PNODE pNew=(PNODE)malloc(sizeof(NODE));
            if(pNew==NULL){
            printf("error");
            }
            pNew->data=val;
            pTail->pNext=pNew;
            pNew->pNext=NULL;
            pTail=pNew;
        }
        return pHead;
    }
    /*显示链表*/
    void show_list(PNODE p){
        PNODE p1=p->pNext;
        if(p1==NULL){
            printf("error");
        }
        while(p1){
            printf("%d",p1->data);
            p1=p1->pNext;
        }
    }
    /*显示链表长度*/
    int show_list_length(PNODE p){
        int count=0;
        PNODE p1=p->pNext;
        if(p1==NULL){
            printf("error");
        }
        while(p1){
            count++;
            p1=p1->pNext;
        }
        return count;
    }
    /*查找第k个节点的值*/
    int serch_k(PNODE p,int k){
    int i=0;
        PNODE p1=p; 
        int len=show_list_length(p);
        if(k>len){
            printf("error");
        }
        /*循环len-k+1次*/
        for(i=0;i<len-k+1;i++){
            p1=p1->pNext;
            
        }
        return p1->data;
    }    

        这个算法需要对链表进行两次遍历,导致时间复杂度为O(N^2),那有没有只需要一次遍历的呢,答案是有的。

        首先先看下思路:p1和p2分别都是head指针,先将p2向右移动k次,如图2所示

     

    图1

        

    图2

         这时候,只需要继续保持p1和p2等间距的右移,当p2的next为null,则证明p1所指的结点的值为倒数第k个节点的值

         

    图3

         这就是一次遍历找出倒数第k个节点的值,其时间复杂度为O(N)

         具体代码如下所示

    int serch_k(PNODE p,int k){
        int i;
        PNODE p1 = p;
            PNODE p2 = p;
        for (i = 0; i < k; i++) {
            p2 = p2->pNext;
        }
        while (p2 != NULL) {
            p1 = p1->pNext;
            p2 = p2->pNext;
    
        }
        return p1->data;
    }

       这是测试结果

     

    图4

       这就是单链表找倒数第k个结点的值的两种方法。

        

  • 相关阅读:
    PHP MVC运用
    17个方法防止dedeCMS织梦网站被黑挂木马
    少有人走的路
    你有选择的自由
    产品经理需要掌握哪些能力
    产品经理的工作流程
    Weave实现跨主机容器互联
    转载【docker】CMD ENTRYPOINT 的使用方法
    Docker:发布镜像问题denied: requested access to the resource is denied的解决方法
    Docker Dockerfile基本配置
  • 原文地址:https://www.cnblogs.com/dirkhe/p/6790858.html
Copyright © 2011-2022 走看看