力扣-147-对链表进行插入排序

ListNode* insertionSortList(ListNode* head) {
	// 待排节点需要和它前面的节点比较?单链表怎么比,单链表的反向遍历?
	// 只能从头开始找
	// 还要手写链表的交换?
	if (!head->next) return head;
	ListNode* dummyNode = new ListNode(-501);
	dummyNode->next = head;
	ListNode* iteratorNode = head->next;
	ListNode* pre = head;
	while (iteratorNode) {
		for (ListNode* it = dummyNode->next, *prepre = dummyNode; it!=iteratorNode; prepre = it, it = it->next) {
			if (it->val > iteratorNode->val) {
				// 插
				pre->next = iteratorNode->next;
				prepre->next = iteratorNode;
				iteratorNode->next = it;
                break;
			}
		}
		pre = iteratorNode;
		iteratorNode = iteratorNode->next;
	}
	return dummyNode->next;
}

好容易写出来他说我超时😂本来用插入排效率就不高啊,那测试数据叫一个恐怖

看看有没有可以优化的地方
算法的时间主要花费在了查找上面,对于数据量大的测试用例而言会超时

要么就用二分查找,也就是二分插入,对前半段有序序列做二分查找

看了一眼官解,大概知道为什么效率这么差了:
对于数组插入排序来说,是直接和上一个比,但是对于链表,没法一直向上比较,就不得不从头开始比
但是!不是每个元素都需要从头开始比,这里我写的代码中pre是当前遍历节点的上一个节点,同时也是有序序列的最后一个节点,它是有序节点中最大的,所以只要大于它的就应该直接跳过,傻傻去从头开始比较的话费时不说,还完全没有意义

ListNode* insertionSortList(ListNode* head) {
	if (!head->next) return head;
	ListNode* dummyNode = new ListNode(-501);
	dummyNode->next = head;
	ListNode* iteratorNode = head->next;
	ListNode* pre = head;
	while (iteratorNode) {
		if (iteratorNode->val < pre->val)
			for (ListNode* it = dummyNode->next, *prepre = dummyNode; it != iteratorNode; prepre = it, it = it->next) {
				if (it->val > iteratorNode->val) {
					// 插
					pre->next = iteratorNode->next;
					prepre->next = iteratorNode;
					iteratorNode->next = it;
					break;
				}
			}
		pre = iteratorNode;
		iteratorNode = iteratorNode->next;
	}
	return dummyNode->next;
}

肯定是还有优化空间,用时相对于官解来说也还有差距

posted @ 2022-11-02 13:55  YaosGHC  阅读(29)  评论(0)    收藏  举报