面试中常见的链表题目

来源:互联网 发布:希捷官方数据恢复 编辑:程序博客网 时间:2024/04/28 18:18

最近参加面试遇到的一些常见的单链表题目,总结思路和实现代码。

1.单链表的反序

2.给单链表建环

3.检测单链表是否有环

4.给单链表解环

5.检测两条链表是否相交

6.不输入头节点,删除单链表的指定节点(只给定待删除节点指针)

7.合并两个有序链表


1.单链表的反序

01//逆转链表,并返回逆转后的头节点 
02node* reverse(node *head) 
03
04    if(head == NULL || head->next == NULL) 
05    
06        returnhead; 
07    
08    node *cur = head; 
09    node *pre = NULL; 
10    node *tmp; 
11    while(cur->next) 
12    
13        tmp = pre; 
14        pre = cur; 
15        cur = cur->next; 
16        pre->next = tmp;                  //操作pre的next逆转 
17    
18    cur->next = pre;                     //结束时,操作cur的next逆转 
19    returncur; 
20}
01//方法二
02node *reverse(node *head)
03{
04    node *p, *q, *r;
05     
06    p = head;
07    q = p->next;
08     
09    while(q != NULL)
10    {
11        r = q->next;
12        q->next = p;
13        p = q;
14        q = r;
15    }
16 
17    head->next = NULL;
18    head = p;
19     
20    return head;
21}

2.给单链表建环

01//给单链表建环,让尾指针,指向第num个节点,若没有,返回false 
02bool bulid_looplink(node *head, intnum) 
03
04    node *cur = head; 
05    node *tail = NULL; 
06    inti = 0; 
07    if(num <= 0 || head == NULL) 
08    
09        returnfalse
10    
11    for(i = 1; i < num; ++i) 
12    
13        if(cur == NULL) 
14        
15            returnfalse
16        
17        cur = cur->next; 
18    
19    tail = cur; 
20    while(tail->next) 
21    
22        tail = tail->next; 
23    
24    tail->next = cur; 
25    returntrue
26}

3.检测单链表是否有环

01//检测单链表是否有环,快慢指针 
02booldetect_looplink(node *head) 
03
04    node *quick_node = head->next, *slow_node = head; 
05    if(head == NULL || head->next == NULL) 
06    
07        returnfalse
08    
09    while(quick_node != slow_node) 
10    
11        if(quick_node == NULL || slow_node == NULL) 
12            break
13        quick_node = quick_node->next->next; 
14        slow_node = slow_node->next; 
15    
16    if(quick_node != NULL && slow_node != NULL)    //非尾节点相遇 
17        returntrue
18    returnfalse
19}

4.给单链表解环

ps:为了增加节点位图的效率,本应使用hash或则红黑树,这里不造车了,直接用 set容器

01//找到有环节点,并解环,找到并解环,返回true,无环,返回false 
02//思路:先找到环节点:被2个节点指向的节点(一定有环的条件)ps:不考虑中间环,因为只有一个next节点,只可能是尾环 
03boolunloop_link(node *head) 
04
05    set<node *> node_bitmap;        //node的地址位图 
06    unsigned intnum = 0; 
07    node *cur = head, *pre = NULL; 
08    while(cur != NULL) 
09    
10        if(!node_bitmap.count(cur) )              //该节点未被遍历过 
11        
12            node_bitmap.insert(cur); 
13            ++num; 
14        
15        else                              //指向已被遍历过的节点,此时pre节点为尾节点 
16        
17            pre->next = NULL; 
18            returntrue
19        
20        pre = cur; 
21        cur = cur->next; 
22    
23    returnfalse
24}
5.检测两条链表是否相交

01//检测两条链表是否相交,是则返回第一个交点,否则返回NULL 
02//思路:把2个链表各遍历一遍,记下长度length1和length2,若2者的尾节点指针相等,则相交。 
03//       之后再把长的链表从abs(len1-len2)的位置开始遍历,第一个相等的指针为目标节点 
04node* detect_intersect_links(node *first_link, node *second_link) 
05
06    intlegnth1 = 1, length2 = 1, pos = 0; 
07    node *cur = NULL, *longer_link = first_link, *shorter_link = second_link; 
08    if(first_link == NULL || second_link == NULL) 
09    
10        returnNULL; 
11    
12    while(first_link->next || second_link->next)     //遍历2个链表 
13    
14        if(first_link->next) 
15        
16            first_link = first_link->next; 
17            ++legnth1; 
18        }
19        if(second_link->next)
20        {
21            second_link = second_link->next;
22            ++length2;
23        }
24    }
25    if(first_link != second_link)                 //比较尾节点 
26    {
27        return NULL;
28    }
29    pos = legnth1 - length2; 
30    if(legnth1 < length2)                  //保证 longer_link为长链表 
31    
32        pos = length2 - legnth1; 
33        cur = longer_link; 
34        longer_link = shorter_link; 
35        shorter_link = cur; 
36    
37    while(pos-- > 0) 
38        longer_link = longer_link->next; 
39    while(longer_link || shorter_link) 
40    
41        if(longer_link == shorter_link)                  //找到第一个交点 
42        
43            returnlonger_link; 
44        
45        longer_link = longer_link->next; 
46        shorter_link = shorter_link->next; 
47    
48    returnNULL; 
49}

6.不输入头节点,删除单链表的指定节点(只给定待删除节点指针)

01//无头节点,随机给出单链表中一个非头节点,删除该节点,当传入空节点,或者尾节点时,返回false 
02//思路:由于没有头节点,非循环单链表,无法获取目标节点的前节点,所以只能把它的next节点数据前移,并删除next节点 
03//ps:当传入节点为尾节点,无法用此方法删除 
04boolwithouthead_delete_node(node *target_node) 
05
06    node *cur = NULL; 
07    if(target_node == NULL || target_node->next == NULL)   //空节点或者尾节点,失败 
08    
09        returnfalse
10    
11    cur = target_node->next; 
12    target_node->name = cur->name; 
13    target_node->next = cur->next; 
14    deletecur; 
15    returntrue
16}

7.合并两个有序链表

001/*
002递归实现:
003①算法思想:
004递归终止条件:若head1为空,返回head2指针(head);若head2为空,返回head1指针(head)
005递归过程:
006 
0071 若head1->data>head2->data;  head 指针应该指向head2所指向的节点,而且head->next应该指向head1和head2->next两个链表的合成序列的头指针;
008 
0092 否则head 指针应该指向head1所指向的节点,而且head->next应该指向head->next和head2两个链表的合成序列的头指针;
010*/
011#include <iostream>
012using namespace std;
013 
014/*节点的类定义*/
015class Node
016{
017public:
018    int data;
019    Node *next;
020    Node(int data)
021    {
022        this->data = data;
023    }
024};
025 
026/*链表的类定义*/
027class LinkedList
028{
029public:
030    Node *head;
031 
032    /*用一个整形数组作为参数的构造函数*/
033    LinkedList(int array[])
034    {
035        head = new Node(array[0]);
036        Node *temp = head;
037        int i;
038        for( i = 1; i < 3; i++ )
039        {
040            temp->next = new Node(array[i]);
041            temp = temp->next;
042        }
043         
044        temp->next = NULL;
045    }
046};
047 
048/*递归的合并两个有序链表*/
049Node * mergeLinkedList(Node *head1, Node *head2)
050{
051    Node *p = NULL;
052     
053    if(head1 == NULL && head2 == NULL)
054        return p;
055    else if(head1 == NULL)
056        return head2;
057    else if(head2 == NULL)
058        return head1;
059    else
060    {
061        if(head1->data < head2->data)
062        {
063            p = head1;
064            p->next = mergeLinkedList(head1->next, head2);
065        }
066        else
067        {
068            p = head2;
069            p->next = mergeLinkedList(head1, head2->next);
070        }
071         
072        return p;
073    }
074}
075 
076/*打印链表的所有元素*/
077void printList(Node *head)
078{
079    Node *temp = head;
080    while(temp != NULL)
081    {
082        cout<<temp->data<<"  ";
083        temp = temp->next;
084    }
085}
086 
087int main()
088{
089    int array1[3] = {2,5,8};
090    int array2[3] = {1,6,7};
091     
092    /*构造两个有序链表--list1和list2*/
093    LinkedList list1(array1);
094    LinkedList list2(array2);
095 
096    /*递归的将这两个有序链表合并成一个有序链表*/
097    Node *new_head = mergeLinkedList(list1.head, list2.head);
098 
099    /*打印有序链表*/
100    printList(new_head);
101 
102    return 0;

103}


         转载于:http://blog.csdn.net/yongjunhe/article/details/8488091

0 0
原创粉丝点击