面试算法题. 单向链表奇偶节点拆分与排序. 链表的基本操作

思路:

  1. 将奇偶节点拆分
  2. 降序链表反转
  3. 两个有序链表合并 
// 链表节点结构
struct ListNode {
	ListNode(int a = 0) : val(a), 
			next(nullptr) {
	}

	int val;
	ListNode* next;
};


// 递归版本的链表反转
ListNode* ReverseList(ListNode* head) {

	if (nullptr == head)
		return nullptr;

	if (nullptr == head->next)
		return head;

	ListNode* newHead = ReverseList(head->next);
	head->next->next = head;
	head->next = nullptr;

	return newHead;
}

// 合并两个有序链表
ListNode* mergeList(ListNode* l1, ListNode* l2) {

	if (nullptr == l1)
		return l2;

	if (nullptr == l2)
		return l1;

	ListNode* newhead = new ListNode(0);
	ListNode*next = newhead;

	while (nullptr != l1 && nullptr != l2) {

		if (l1->val <= l2->val) {

			next->next = l1;
			l1 = l1->next;
		}
		else {
			next->next = l2;
			l2 = l2->next;
		}
		next = next->next;
	}

	next->next = nullptr != l1 ? l1 : l2;
	ListNode* p = newhead;
	delete p;// 需要释放开辟的临时内存

	newhead = newhead->next;
	return newhead;
}

// 链表的奇偶拆分,头节点指定为1,为奇数节点
// 这里假定奇数为升序,偶数为降序
ListNode* SplitList(ListNode* head) {

	if (nullptr == head)
		return head;

	// 奇偶链表分离
	ListNode *h1 = head;
	ListNode *h2 = head->next;
	ListNode *p2 = h2;

	while (nullptr != h1 && nullptr != h2) {

		h1->next = h2->next;
		h1 = h1->next;
		h2->next = nullptr != h1 ? h1->next : nullptr;
		h2 = h2->next;
	}

	h1 = head;
	h2 = p2;

	// 对偶数链表做一个逆序
	h2 = ReverseList(h2);

	// 最后对两个升序链表进行一个合并
	return mergeList(h1, h2);
}

猜你喜欢

转载自blog.csdn.net/paradox_1_0/article/details/106312765