单链表的快速排序算法及其实现

今天听同学面友录说道单链表是否可以用快速排序算法,想起自己面百度一面的时候面试官也面到这个问题,由于本人是个小菜鸟,所以花了一个下午的时间整理了一下。


算法思想对于一个链表,以head节点的值作为key,然后遍历之后的节点,可以得到一个小于key的链表和大于等于key的链表;由此递归可以对两个链表分别进行快速。这里用到了快速排序的思想即经过一趟排序能够将小于key的元素放在一边,将大于等于key的元素放在另一边;


面试回答:如果面试官问快速排序是否适合单链表,答案当然是不适合;但是如果问单链表可不可以用快速排序,答案当然是肯定的;下面贴出一段拙劣的代码,希望大家修正!


code:

struct LinkNode{
	int value;
	LinkNode* next;
	LinkNode(): value(0), next(NULL) {};
};


void Quicksort(LinkNode* &head, LinkNode* &end){
	LinkNode *head1, *head2, *end1, *end2;	/*	记录每次分割后前后两个链表的头尾节点*/
	head1 =  head2 = end1 = end2  = NULL;	
	
	if( head == NULL ) return;	//如果遍历的当前节点为空,返回

	LinkNode *p, *pre1, *pre2;	/*用于遍历链表将链表中的元素分成大于key和小于key两个部分*/
	p = pre1 = pre2 = NULL;
	
	int key = head->value;
	p = head->next; head->next = NULL;	//将head的值孤立出来
	while( p != NULL ) {
		//小于key的链表
		if ( p->value < key ){
			if( !head1 ) { head1 = p; pre1 = p; }
			else{ pre1->next = p; pre1 = p; }
			p = p->next;
			pre1->next = NULL;
		}
		//大于等于key的链表
		else{
			if( !head2 ) { head2 = p; pre2 = p; }
			else { pre2->next = p; pre2 = p; }
			p = p->next;
			pre2->next = NULL;
		}
	}

	end1 = pre1; end2 = pre2;	/*产生新链表的首尾节点*/

	//对左右两个链表进行递归快排
	Quicksort(head1, end1);
	Quicksort(head2, end2);

	//从递归栈返回的时候,将key节点和左右两个链表连起来
	//左右链表都存在
	if( end1 && head2){
		end1->next = head;	head->next = head2;
		head = head1;	end = end2;}

	//只有左链表
	else if(end1) { 
		end1->next = head; 
		end = head;	head = head1; } 

	//只有右链表
	else if(head2){ 
		head->next = head2;	end = end2;} 
}

    原文作者:排序算法
    原文地址: https://blog.csdn.net/panghuizl/article/details/6984026
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞