链表常见题目

来源:互联网 发布:威图网络柜图片 编辑:程序博客网 时间:2024/06/06 18:24

链表题目

结构

struct ListNode {    ListNode(int x) :        val(x), next(nullptr) {    }    int val;    struct ListNode *next;};

1.求链表中结点个数

int GetList_num(ListNode*head){    if (head == nullptr)        return 0;    int count = 0;    ListNode*p = head;    while (p){        count++;        p = p->next;    }    return count;}

2.反转一个单链表

ListNode*reverse_list(ListNode*head){    if (head == nullptr || head->next == nullptr)        return head;    ListNode * p_rhead = nullptr;    ListNode * p_current = head;    /*此处进行特别处理,当只有一个结点的时候就这么搞*/    while (p_current)    {        ListNode*ptemp = p_current;        p_current = p_current->next;        ptemp->next = p_rhead;        p_rhead = ptemp;    }    return p_rhead;}

3.查找单链表中倒数第k个结点

ListNode*Get_kthnode(ListNode*phead, int k){    if (k == 0 || phead == nullptr)        return nullptr;    /*如果结点为空或者没有结点返回空*/    ListNode*pheadA = phead;    ListNode*pheadB = phead;    while (k < 1 && pheadA != nullptr)    {        k--;/*先从头往后找(k-1)个位置*/        pheadA = pheadA->next;    }/*此时进行判断k是否是大于1的,如果大于1说明结点不够k个*/    if (k>1 || pheadA == nullptr)        return nullptr;    while (pheadA->next)    {        pheadB = pheadB->next;        pheadA = pheadA->next;    }    return pheadB;    //然后往后面数,一个指针为空的时候另一个指针所指向的就是要求的结点位置}

4.倒序打印链表

void  Rprintlist(ListNode*head){/*利用栈,先进后出的性质去,倒序输出一个链表*/    stack<ListNode*>s;    ListNode*p = head;    while (p){        s.push(p);        p = p->next;    }//使用栈这种结构来存储每个结点    while (!s.empty())//然后将栈内的元素挨个弹出    {        p = s.top();        cout << p->val;        s.pop();    }}

5.判断单链表是否有环

bool hascircle(ListNode*head){    ListNode*pfast = head;    ListNode*pslow = head;    /*此方法使用快慢指针的方式进行处理      当快指针追上慢指针的时候,就说明有环    */    while (pfast != nullptr&&pfast->next != nullptr)    {        pfast = pfast->next->next;        pslow = pslow->next;        if (pslow == pfast)            return true;    }    return false;}

6.寻找链表中间结点

ListNode*GetMiddle_node(ListNode*head){    if (head == nullptr || head->next == nullptr)        return head;    ListNode*pheadA = head;    ListNode*pheadB = head;    while (pheadA->next != nullptr){        pheadA = pheadA->next;        pheadB = pheadB->next;        if (pheadA->next != nullptr)            pheadA = pheadA->next;        /*上面已经走了一步,这里又多走一步*/    }    return pheadB;} /*快慢指针,快指针每次走两步,慢指针每次走一步,当快指针走到末尾的时候,慢指针刚好走到中间位置*/

7.合并两个有序的单链表

ListNode*merge_list(ListNode* l1, ListNode*l2){    ListNode dummy(INT_MIN);    ListNode*tail = &dummy;    while (l1&&l2)//两者都为真的时候才会往下执行,当有一个为假的时候就停止呢    {        if (l1->val < l2->val)        {            tail->next = l1;            l1 = l1->next;        }        else        {            tail->next = l2;            l2 = l2->next;        }        tail = tail->next;    }//到下面这句的时候肯定有一个为假    return tail->next = l1 ? l1 : l2;}//如果l1为空的时候,将l2连接起来;当l2为空的时候,将l1连接起来

8.判断两个单链表是否有交点

题目:两个单链表,人字形结构的链表,从两个链表的头开始,然后挨个遍历,遍历到最后的时候,如果结点相同,那么就说明两个链表有交点

bool IsInter_sect(ListNode*phead1, ListNode*phead2){    if (phead1 == nullptr|| phead2 == nullptr)        return false;    ListNode*ptail1 = phead1;    while (ptail1->next != nullptr)        ptail1 = ptail1->next;    ListNode*ptail2 = phead2;    while (ptail2->next != nullptr)        ptail2 = ptail2->next;    return ptail1 == ptail2;}

9.求两个单链表相交的第一个结点

ListNode*Getfirst_common_node(ListNode*phead1, ListNode*phead2){    if (phead1 == nullptr || phead2 == nullptr)        return nullptr;    int len1 = 1;    ListNode*ptail1 = phead1;    while (ptail1->next != nullptr)    {        len1++;        ptail1 = ptail1->next;    }    int len2 = 1;    ListNode*ptail2 = phead2;    while (ptail2->next != nullptr)    {        len2++;        ptail2 = ptail2->next;    }    if (ptail1 != ptail2)        return nullptr;    /*首先去判断两个链表是否有交点,并统计链表结点个数*/    ListNode*pnode1 = phead1;    ListNode*pnode2 = phead2;    /*如果l1的长度大于l2那么就遍历l1,就从l1开始遍历,否则从l2开始遍历*/    if (len1 > len2)    {        int k = len1 - len2;        while (k--)            pnode1 = pnode1->next;    }    else    {        int k = len2 - len1;        while (k--)            pnode2 = pnode2->next;    }    while (pnode1 != pnode2)    {        pnode1 = pnode1->next;        pnode2 = pnode2->next;    }    return pnode1;}/*当长的减去短的时候,就处于同一位置了,然后同时往后跑,当指针指向的内容相同的时候,就可以找到交点的位置*/

10.已知一个链表有环,求链表的交点

ListNode*get_first(ListNode*head){    ListNode*slow = head;    ListNode*fast = head;    while (fast&&fast->next != nullptr)    {        slow = slow->next;        fast = fast->next->next;        /*快慢指针问题,这里是有规律的,另外找一个指针A,A指针从头开始跑        快慢指针相遇的地方为B,此时A和B同时往后面走,当两个结点相遇的时候,        此结点为环的结点        */        if (fast == slow)        {            ListNode*slow2 = head;            while (slow2 != slow)            {                slow = slow->next;                slow2 = slow->next;            }            return slow2;        }        return nullptr;    }}

总结

    以上包括了大部分链表的大部分笔试题目,一般互联网公司的笔试题目是不会出这种测试题目,都会讲一个故事,让你通过故事去建立相对应的模型。    但是这种题目非常经典,一般出现在现场面试或笔试中。
原创粉丝点击