链表的QuickSort快速排序法

使用QuickSort快速排序算法,排序一个链表。

下面是quickSort,因为quickSort算法的最坏情况是O(n*n), 所以如果做LeetCode上的Sort List这道题目,会遇上最坏情况超时的,不过这是个很好的算法,故此贴出来。

参考网站:

http://www.geeksforgeeks.org/quicksort-on-singly-linked-list/


也看了有些博客或什么网站也写有quickSort排序链表的文章,注意看清楚了,很多并不是真正的链表排序,而是排序了链表的值,那样并不是链表操作,不能算链表的quicksort。


有几个地方需要注意的:

1 分成两个链表的时候,注意把结尾=NULL,重新合并中间的pivot不要忘了,不然会断链的。

2 指针传递要注意:指针值传递和指针地址传递


class Solution2QuickSort {
public:
	ListNode *sortList(ListNode *head) 
	{
		return quickSort(head, getTail(head));
	}

	ListNode *getTail(ListNode *h)
	{
		while (h && h->next) h = h->next;
		return h;
	}

	ListNode *partition(ListNode *h, ListNode *t, ListNode **nh, ListNode **nt)
	{
		ListNode *pivot = t;
		ListNode *pre = NULL, *cur = h, *tail = t;

		while (cur != pivot)
		{
			if (cur->val < pivot->val)
			{
				if (!(*nh)) (*nh) = cur;	//注意:不能是nh=&cur
				pre = cur;
				cur = cur->next;
			}
			else
			{
				if (pre) pre->next = cur->next;
				ListNode *tmp = cur->next;
				cur->next = pivot->next;
				pivot->next = cur;
				cur = tmp;
				if (tail == t) tail = tail->next;
			}
		}
		if (!(*nh)) (*nh) = pivot;
		(*nt) = tail;

		return pivot;
	}

	ListNode *quickSort(ListNode *h, ListNode *t)
	{
		if (!h || h == t) return h;

		ListNode *nh = nullptr, *nt = nullptr;

		ListNode *pivot = partition(h,t,&nh,&nt);

		if (nh != pivot)
		{
			ListNode *tmp = nh;
			while (tmp->next != pivot) tmp = tmp->next;
			tmp->next = nullptr;

			nh = quickSort(nh, tmp);

			tmp = getTail(nh);
			tmp->next = pivot;
		}

		pivot->next = quickSort(pivot->next, nt);

		return nh;
	}
};





链表的QuickSort快速排序法

上一篇:算法之计算 整数乘法


下一篇:Linux下开发关于Samba/Vimrc/svn/tftp/等基本的配置使用