数据结构: 反转链表

数据结构: 反转链表

反转单链表

ListNode* reverseLinkList(ListNode* head) {
	// 仅有一个或为空,返回自身
	if (head == NULL || head->next == NULL) {
		return head;
	}
	ListNode* pre = head;
	ListNode* cur = head->next;
	while (cur != NULL) {
		if (pre == head) {
			pre->next = NULL;
		}
		ListNode* next = cur->next;
		cur->next = pre;
		pre = cur;
		cur = next;
	}
	return pre;  
}
// 反转链表,逐一节点改变指针指向
ListNode* reverseLinkList2(ListNode* head) {
	ListNode* pre = NULL;
	ListNode* next = NULL;
	while (head!=NULL) {
		next = head->next;
		head->next = pre;
		pre = head;
		head = next;
	}
	return pre;
}

反转双向链表

// 反转双向链表
DoubleLinkNode* reverseDoubleLink(DoubleLinkNode* head) {

	DoubleLinkNode* pre = NULL;
	DoubleLinkNode* next = NULL;
	DoubleLinkNode* cur = head;
	while (cur != NULL) {
		next = cur->next;

		cur->next = pre;
		cur->last = next;

		pre = cur;
		cur = next;
	}
	return pre;
}

反转部分单向链表

给定一个头结点head,以及两个整数,from和to.

反转第from个节点到第to个节点这一部分.

返回新的链表的头结点

ListNode* reversePart(ListNode* head, int from, int to) {

    int len = 0;
    ListNode* p = head;
    ListNode* fPre = NULL;
    ListNode* tPos = NULL;

    // 统计长度,同时记录 from的前一个和to的后一个节点
    while (p != NULL) {
        len++;
        fPre = len == from - 1 ? p : fPre;
        tPos = len == to + 1 ? p : tPos;
        p = p->next;
    }

    // 不在有效范围内返回空
    if (from > to || from<1 || to>len) {
        return head;
    }
    /*
		反转之前: fPre f ... t tPos
		反转之后: fPre t ... f tPos
		若fPre不为空,则fPre->next = t, 返回原来的头结点
		若fPre为空,则返回的是 t
	*/
    p = fPre == NULL ? head : fPre->next;
    ListNode* q = p->next;
    ListNode* next = NULL;
    // p表示的是q的前一个节点
    // q表示当前访问的节点,它从 [from ... to] 的第二个节点开始
    // next用于链表断开保存q下一个节点
    while (q != tPos) {
        next = q->next;
        q->next = p;
        p = q;
        q->next;
    }
    if (fPre != NULL) {
        fPre->next = p;
        return head;
    }

    return p;
}

体会

  • 链表的反转需要一个节点一个节点的做.
  • 注意保存将会被断开的节点

猜你喜欢

转载自blog.csdn.net/qjh5606/article/details/85346176
今日推荐