链表

作者: 天涯的尽头s风沙 | 来源:发表于2019-06-19 14:49 被阅读7次
    • 现在有一个单向链表,谈一谈,如何判断链表中是否出现了环

    考察点:链表
    参考回答:
    单链表有环,是指单链表中某个节点的next指针域指向的是链表中在它之前的某一个节点,这样在链表的尾部形成一个环形结构。
    // 链表的节点结构如下 typedef struct node { int data; struct node *next; } NODE;
    最常用方法:定义两个指针,同时从链表的头节点出发,一个指针一次走一步,另一个指针一次走两步。如果走得快的指针追上了走得慢的指针,那么链表就是环形链表;如果走得快的指针走到了链表的末尾(next指向 NULL)都没有追上第一个指针,那么链表就不是环形链表。
    通过使用STL库中的map表进行映射。首先定义 map<NODE *, int> m; 将一个 NODE * 指针映射成数组的下标,并赋值为一个 int 类型的数值。然后从链表的头指针开始往后遍历,每次遇到一个指针p,就判断 m[p] 是否为0。如果为0,则将m[p]赋值为1,表示该节点第一次访问;而如果m[p]的值为1,则说明这个节点已经被访问过一次了,于是就形成了环。

    • 谈一谈,bucket如果用链表存储,它的缺点是什么?

    考察点:链表
    参考回答:

    ①查找速度慢,因为查找时,需要循环链表访问

    ②如果进行频繁插入和删除操作,会导致速度很慢。

    • 有一个链表,奇数位升序偶数位降序,如何将链表变成升序

    考察点:链表
    参考回答:

    public class
    OddIncreaseEvenDecrease {
        /**
         * 按照奇偶位拆分成两个链表
         * @param head
         * @return
         */
        public static Node[] getLists(Node head){
            Node head1 = null;
            Node head2 = null;
            
            Node cur1 = null;
            Node cur2 = null;
            int count = 1;//用来计数
            while(head != null){
                if(count % 2 == 1){
                    if(cur1 != null){
                        cur1.next = head;
                        cur1 = cur1.next;
                    }else{
                        cur1 = head;
                        head1 = cur1;
                    }
                }else{
                    if(cur2 != null){
                        cur2.next = head;
                        cur2 = cur2.next;
                    }else{
                        cur2 = head;
                        head2 = cur2;
                    }
                }
                head = head.next;
                count++;
            }
            //跳出循环,要让最后两个末尾元素的下一个都指向null
            cur1.next = null;
            cur2.next = null;
            
            Node[] nodes = new Node[]{head1,
    head2};
            return nodes;
        }
        
        /**
         * 反转链表
         * @param head
         * @return
         */
        public static Node reverseList(Node head){
            Node pre = null;
            Node next = null;
            while(head != null){
                next = head.next;
                head.next = pre;
                pre = head;
                head = next;
            }
            return pre;
        }
         
        /**
         * 合并两个有序链表
         * @param head1
         * @param head2
         * @return
         */
        public static Node CombineList(Node head1,
    Node head2){
            if(head1 == null || head2 == null){
                return head1 != null ? head1 :
    head2;
            }
            Node head = head1.value < head2.value ?
    head1 : head2;
            Node cur1 = head == head1 ? head1 :
    head2;
            Node cur2 = head == head1 ? head2 :
    head1;
            Node pre = null;
            Node next = null;
            while(cur1 != null && cur2 !=
    null){
                if(cur1.value <= cur2.value){//这里一定要有=,否则一旦cur1的value和cur2的value相等的话,下面的pre.next会出现空指针异常
                    pre = cur1;
                    cur1 = cur1.next;
                }else{
                    next = cur2.next;
                    pre.next = cur2;
                    cur2.next = cur1;
                    pre = cur2;
                    cur2 = next;
                }
            }
            pre.next = cur1 == null ? cur2 : cur1;
            
            return head;
        }
        
    }
    
    • 随机链表的复制

    考察点:链表
    参考回答:

    public RandomListNode copyRandomList(RandomListNode head) {
      
        if (head == null)
            return null;
      
        RandomListNode p = head;
      
        // copy every node and insert to list
        while (p != null) {
            RandomListNode copy = new RandomListNode(p.label);
            copy.next = p.next;
            p.next = copy;
            p = copy.next;
        }
      
        // copy random pointer for each new node
        p = head;
        while (p != null) {
            if (p.random != null)
                p.next.random = p.random.next;
            p = p.next.next;
        }
      
        // break list to two
        p = head;
        RandomListNode newHead = head.next;
        while (p != null) {
            RandomListNode temp = p.next;
            p.next = temp.next;
            if (temp.next != null)
                temp.next = temp.next.next;
            p = p.next;
        }
      
        return newHead;
    }
    
    • 如何反转单链表

    考察点:链表
    参考回答:

    ListNode
    reverseList(ListNode* head) {
            if(head == nullptr || head->next ==
    nullptr)
                return head;
            ListNode* p;
            ListNode* q;
            ListNode* r;
            p = head;
            q = head->next;
            head->next = nullptr;//旧的头指针是新的尾指针 指向NULL
            while(q){
                r = q->next;//用来保存下一步要处理的指针
                q->next = p;//p q 交替处理 进行反转单链表
                p = q;
                q = r;
            }
            head = p;//最后的q必定指向NULL,p就成了新链表的头指针
            return head;
    }
    

    相关文章

      网友评论

        本文标题:链表

        本文链接:https://www.haomeiwen.com/subject/jwkkqctx.html