单链表 以及用链表解决常用面试算法的问题

单链表在插入和删除的时候容易出现空指针异常

1.当进行链表插入的时候

newNode->next=p->next;
p->next=newNode

//当插入首个节点的时候需要注意
if(head==NULL)
    head=newNode;

2.当在删除链表的时候需要注意链表的表尾问题

if(head->next==NULL)
{
    head=NULL;  
}

3 在使用链表的过程中边界问题是需要判断的

4. 当引入哨兵的时候可以通过技巧跳过边界问题,在头结点的前面加入一个哨兵节点,哨兵节点不参与实际数据,有了哨兵节点,在添加元素的时候就不需要判断链表边界问题

链表的反转

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    ListNode* reverseList(ListNode* head) {
        ListNode *cur;
        ListNode *pre=NULL;
        ListNode *next=NULL;
        if(head==NULL){
            return NULL;
        }
        cur=head;
        while(cur->next!=NULL){
            next=cur->next;
            cur->next=pre;
            pre=cur;
            cur=next;
        }
        cur->next=pre;
        return cur;
    }
};

两个有序链表的合并,参考LeetCode解,加入哨兵,防止边界报空

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) {
        ListNode head(0);
        ListNode* node=&head;
        while(l1 && l2){
            ListNode ** nextNode=l1->val > l2->val?&l2:&l1;
            node->next= *nextNode;
            *nextNode = (*nextNode)->next;
            node = node->next;
        }
        node->next = (l1!=NULL)?l1:l2;
        return head.next;
    }
};

 环形链表

  

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    bool hasCycle(ListNode *head) {
        ListNode* slow=head, *fast=head;
        while (slow && fast && fast->next) {
            slow=slow->next;
            fast=fast->next->next;
            if(slow==fast) return true;
        }
        return false;
    }
};

删除链表中的第k个节点,加入哨兵,防止边界报空问题

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    ListNode* removeNthFromEnd(ListNode* head, int n) {
        ListNode *newNode=new ListNode(0);
        newNode->next=head;
        ListNode* first=newNode;
        ListNode* second=newNode;
        for(int i=0;i<n+1;i++){
            first=first->next;
        }
        while(first!=NULL){
            first=first->next;
            second=second->next;
        }
        second->next=second->next->next;
        return newNode->next;
    }
};
原文地址:https://www.cnblogs.com/huangzhenxiong/p/10133780.html