输出链表中倒数第k个结点

题目:输入一个单向链表,输出该链表中倒数第k个结点。最后一个结点为倒数第一个结点。

思路:

1.首先遍历链表的长度获得链表的length,则它的倒数第k个结点就是正数length-k+1个结点,但这需要遍历链表两次

2.使用两个指针可以实现遍历一次,first指针指向头结点,second指针指向first之后的k-1个结点,然后两个结点循环向后移动,直到second结点到达链表的最后一个结点时,first结点指向倒数第k个结点。

注意:

1.要判断传来的参数 *head和k是否合法

2.判断k是否超过链表的长度。

代码如下:

struct listnode
{
    int data;
    listnode *next;
};
//使用尾插法构建链表
listnode *init()
{
    listnode *head=(listnode *)malloc(sizeof(listnode));
    head->next=NULL;
    listnode *last=head;
    int data;
    cout<<"请输入:(按-1结束链表)"<<endl;
    cin>>data;
    while(data!=-1)
    {
        listnode *temp=(listnode *)malloc(sizeof(listnode));
        temp->data=data;
        temp->next=last->next;//last的下一个为NULL
        last->next=temp;
        last=temp;
        cout<<"请输入:(按-1结束链表)"<<endl;
        cin>>data;
    }
    return head;
}
//打印链表
void print(listnode *head)
{
    listnode *temp=head->next;
    while(temp!=NULL)
    {
        cout<<"  "<<temp->data;
        temp=temp->next;
    }
}
//找到链表的第k个结点
listnode *findnumberK(listnode *head,unsigned int k)
{
    //判断参数是否正确
    if(head==NULL||k==0)
    {
        return NULL;
    }
    listnode *first=head;
    listnode *second=first;
    //第二个指针向前走k-1次
    for(int i=0;i<k-1;i++)
    {
        //判断第二个指针的next是否为空
        if(second->next!=NULL)
            second=second->next;
        //没有第k个结点
        else
            return NULL;
    }
    //两个指针循环向前走,第二个指针到达链表结尾,则第一个指针到达第k个结点
    while(second->next)
    {
        first=first->next;
        second=second->next;
    }
    return first;
}

测试代码以及运行结果:

int main()
{
    listnode *head=init();
    print(head);
    cout<<endl;
    cout<<findnumberK(head,3)->data<<endl;
    return 0;
}

原文地址:https://www.cnblogs.com/runninglzw/p/4527955.html