• 【编程题目】输入一个单向链表,输出该链表中倒数第 k 个结点


    第 13 题(链表):
    题目:输入一个单向链表,输出该链表中倒数第 k 个结点。链表的倒数第 0 个结点为链表
    的尾指针。
    链表结点定义如下:
    struct ListNode
    {
    int m_nKey;
    ListNode* m_pNext;
    };

    我的思路:先翻转链表,再从翻转后的链表的头向尾数k-1个,返回,再次翻转链表。

    代码如下:注意这个思路非常差。差的原因是:如果只是用最原始的方法,先遍历一遍计数,再遍历一遍找倒数第k个,需要遍历两遍。但我的思路,翻转两次链表就要遍历两遍。还要在走k-1步找倒数第k个。繁琐至极。

    /*
    第 13 题(链表):
    题目:输入一个单向链表,输出该链表中倒数第 k 个结点。链表的倒数第 0 个结点为链表
    的尾指针。
    链表结点定义如下: 
    struct ListNode 
    {
    int m_nKey;
    ListNode* m_pNext;
    };
    start time = 20:40
    end time
    */
    
    #include <stdio.h>
    #include <stdlib.h>
    
    typedef struct ListNode 
    {
        int m_nKey;
        ListNode* m_pNext;
    }ListNode;
    
    ListNode * reverseList(ListNode * L)
    {
        ListNode * pp = L;
        ListNode * p = L->m_pNext;
        pp->m_pNext = NULL;
        while (p != NULL)
        {
            ListNode * p3 = p->m_pNext;
            p->m_pNext = pp;
            pp = p;
            p = p3;
        }
    
        return pp;
    }
    
    ListNode * getKthNodeFromBack(ListNode * L, int k)
    {
        if(k == 0)
            return NULL;
        ListNode * rL = reverseList(L);
        ListNode * p = rL;
        for (int i = 0; p != NULL && i < k-1; i++) //注意检测k不能超过链表长度,否则返回NULL
        {
            p = p->m_pNext;
        }
        reverseList(rL);
        return p;
    }
    
    void displayList(ListNode * L)
    {
        ListNode * p = L;
        while (p != NULL)
        {
            printf("%d ",p->m_nKey);
            p = p->m_pNext;
        }
        printf("
    ");
    }
    
    void createList(ListNode * &L)
    {
        int d;
        scanf("%d",&d);
        if (d != 0)
        {
            L = (ListNode *)malloc(sizeof(ListNode));
            L->m_nKey = d;
            L->m_pNext = NULL;
            createList(L->m_pNext);
        }
    }
    
    int main()
    {
        ListNode * L = NULL;
        createList(L);
        ListNode * pk = getKthNodeFromBack(L, 3);
        displayList(L);
    
        return 0;
    }

    网上的思路:http://blog.sina.com.cn/s/blog_60c8379d01013z0s.html

    分析:使用两个指针,low,fast,先把fast的指针指向第k个元素,然后low和fast同时向后遍历,当fast遍历到结尾时,low正好遍历到倒数第k个。注意边界和指针是否为空的检测,注意k是否超过链表长度。

    LinkList.h 
    
    #ifndef LINKLIST_H
    #define LINKLIST_H
    #include <stdlib.h>
    #include <stdio.h>
    #include <iostream>
    using namespace std;
    
    typedef struct node{
    int val;
    struct node *next;
    }node,*pNode;
    
    pNode CreateLinkList(pNode &T);
    pNode FindLastKth(pNode T,int k);
    #endif
    
    LinkList.cpp
    #include "LinkList.h"
    pNode CreateLinkList(pNode &T){
    int ival;
    cin>>ival;
    if(ival==0)
    return NULL;
    T = (pNode)malloc(sizeof(node));
    T->val = ival;
    T->next = NULL;
    T->next = CreateLinkList(T->next);
    return T;
    }
    pNode FindLastKth(pNode T,int k){
    pNode low=T,fast = T;
    for(int i=0;i<k&&fast!=NULL;i++){
    fast = fast->next;
    }
    if(fast == NULL)
    return NULL;
    while(fast!=NULL){
    fast = fast->next;
    low = low->next;
    }
    return low;
    }
    Main.cpp #include
    "LinkList.h" void main(){ pNode T; T = NULL; CreateLinkList(T); int k=3; pNode pnode; pnode = FindLastKth(T,k); cout<<pnode->val; system("pause"); }
  • 相关阅读:
    centos下vsftpd不能显示文件,不能创建文件及文件夹
    PHP过滤常用标签的正则表达式
    px、dp、sp、mm、in、pt这些单位有什么区别?
    Android Studio升级后报 method not found: 'runProguard'的错误
    Android应用签名
    Android技巧小结之新旧版本Notification
    java中 synchronized 的使用,确保异步执行某一段代码。
    android开发笔记(二)导入项目到eclipse和另一个项目
    android开发笔记(一)Android studio 输入法
    这个算asp.net的一个bug吗?
  • 原文地址:https://www.cnblogs.com/dplearning/p/3972226.html
Copyright © 2020-2023  润新知