数据结构——反转链表

单向链表:

class ListNode{ //单向链表
public:
    int val;
    ListNode* next;
    ListNode(int x) : val(x) {}
    ListNode() = default;
};

递归反转单向链表:

反转全部:

ListNode* reverse_L(ListNode* head){
    if(!head->next) return head;
    ListNode* last = reverse_L(head->next);
    head->next->next = head;
    head->next = nullptr;
    return last;
}

反转前n个节点:

ListNode_D* tmp;
ListNode_D* reverse_LN(ListNode_D* head, int n){
    if(n == 1){
        tmp = head->next;
        return head;
    }
    ListNode_D* last = reverse_LN(head->next, n - 1);
    head->next->next = head;
    head->next = tmp;
    return last;
}

反转[l,r]节点位置的链表:

ListNode_D* reverse_DLN(ListNode_D* head, int l, int r){
    if(l == 1){
        return reverse_LN(head, r);
    }
    head->next = reverse_DLN(head->next, l - 1, r - 1);
    return head;
}

迭代翻转链表:

反转(l,r)区间的链表:

ListNode_D* reverse_a_b(ListNode_D* a, ListNode_D* b){  //a~b开区间的链表
    if(a == b || a->next == b) return a;	//如果a~b之间没有可转节点或者a==b,直接返回
    ListNode_D *pre, *cur, *nxt;	//记录前一个节点、目前节点、后一个节点
    //注意初始前一个节点需要为a,这样经过一轮循环之后,
    //a与a->next相互指向
    pre = a, cur = a->next;		
    do{	//每一次循环都会将pre与cur节点翻转过来。
        nxt = cur->next;
        cur->next = pre;
        pre = cur;
        cur = nxt;
    } while(cur != b);
    a->next->next = b;
    a->next = pre;
    return a;
}

判断回文链表(递归):

递归法判断:

ListNode_D* leaf;   //判断回文链表,用递归形式
bool judge_D_palindrome(ListNode_D* right){
    if(!right) return true;
    bool res = judge_D_palindrome(right->next);
    res = res && (leaf->val == right->val);
    leaf = leaf->next;
    return res;
} 
bool judge_D(ListNode_D* head){
    leaf = head;
    return judge_D_palindrome(head);
}

快慢指针判别法:

bool judge_D_palindrom_double(ListNode_D* head){
    ListNode_D *fast = head, *slow = head;
    while(fast && fast->next){
        fast = fast->next->next;
        slow = slow->next;
    }
    if(fast) slow = slow->next;
    ListNode_D *left = head;
    ListNode_D *right = reverse_DL(slow);
    while(right){
        if(right->val != left->val) return false;
        right = right->next;
        left = left->next;
    }
    return true;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值