• 数据结构-链表中倒数第K个节点


    题目:输入一个链表,输出该链表中倒数第K个节点。为了符合大多数人的习惯,本题从1开始计数,即链表的尾节点是倒数第1个节点。例如一个链表有6个节点,从头节点开始他们的值依次为1,2,3,4,5,6.这个链表的倒数第三个节点是值为4的节点。

    分析:不能多次遍历链表,只能一次遍历。

    /*
    剑指offer面试题15
    */
    #include <iostream>
    
    using namespace std;
    
    struct ListNode{
        ListNode* Next;
        int data;
    };
    
    
    /*
    把题目看错,看成删除了。但是删除功能可以实现,
    同样存在和题目一样的问题,存在多次遍历问题。
    为了代码质量更好要求只遍历一次。
    */
    ListNode* DeleteKnode(ListNode** head,int k){
        if(*head == NULL || k <= 0){
            return NULL;
        }
    
        ListNode* p = *head;
        ListNode* q = new ListNode;
        int count = 0;
        int num = 0;
    
        while(p != NULL){
            p = p->Next;
            count++;
        }
        //加入k大于链表长度,非法
        if(k > count){
            return NULL;
        }
        //删除尾节点
        if(k == 1){
            p = *head;
            int i=1;
            while(i<(count-1)){
                p = p->Next;
                i++;
            }
            q = p->Next;
            delete q;
            q = NULL;
            p->Next = NULL;
            return *head;
        }
        //删除头节点
        if(k == count){
            p = *head;
            q = p->Next;
            delete p;
            p = NULL;
            return q;
        }
    
        else{
            p = *head;
            while(p != NULL && (count-k-1) > num){
                num++;
                p = p->Next;
            }
            q = p->Next;
            p->Next = q->Next;
            delete q;
            q = NULL;
        }
    
        return p;
    }
    
    void Print(ListNode** head,int k){
        if(*head == NULL || k <= 0){
            return;
        }
    
        ListNode* first = *head;
        int length = 0;
        for(int i=0;i<k-1;++i){
            if(first->Next != NULL){    //这是关键步骤!!
                first = first->Next;
                length++;
            }
            else{
                return;
            }
        }
    
        ListNode* second = *head;
        while(first->Next != NULL){
            first = first->Next;
            length++;
            second = second->Next;
        }
    
        cout << second->data << endl;
    
    }
    
    int main()
    {
        ListNode* head = new ListNode;
        ListNode* One = new ListNode;
        ListNode* Two = new ListNode;
        ListNode* tail = new ListNode;
    
        head->data = 0;
        head->Next = One;
        One->data = 1;
        One->Next = Two;
        Two->data = 2;
        Two->Next = tail;
        tail->data = 3;
        tail->Next = NULL;
    
        int k;
    
        cin >> k;
    
    /*
        ListNode* p = DeleteKnode(&head,k);
    
        while(p != NULL){
            cout << p->data << " ";
            p = p->Next;
        }
    */
    
        Print(&head,k);
    
        return 0;
    }
  • 相关阅读:
    使用TCP
    socket基本
    windows内核原理及实现-----进程线程管理------3.4节中 windows中进程句柄
    windows内核原理及实现-----进程线程管理------3.3节中 windows中进程线程的数据结构
    winDBG用法
    windows调试异常机制
    MYSQL5上运行多个实例
    Mysql双主实战
    Mysql-Proxy使用
    新的旅程
  • 原文地址:https://www.cnblogs.com/wn19910213/p/3723347.html
Copyright © 2020-2023  润新知