单链表之快排

http://fengchangjian.com/?p=1330

快排最核心的思想就是划分,确定一个枢轴元素(pivot),每一趟划分的目的就是把待排序列分为两部分,前一部分比枢轴小(序列A),后一部分比枢轴大(序列B)。经过一趟划分之后序列变为:{A} pivot {B}。以下是具体步骤:
1、确定每一次划分的枢轴元素为当前待排序列的头节点。
2、设置Slow和Fast两个游标,Slow指向序列A中的最后一个元素,初始化为枢轴本身(待排序列头节点)。让Fast遍历一遍待排序列,当所指元素比枢轴小时,将Slow往前游一格,交换Slow和Fast所指元素的值,这样仍能保证Slow指向的元素是序列A中的最后一个元素。
3、交换Slow所指元素和枢轴元素的值。
4、对序列A和B重复步骤1~4。

下面是单链表快速排序算法的Java实现:
1、单链表节点的定义。


/**
 * @param ListHead 待排序列的头节点
 * @param ListEnd 待排序列的尾节点
 */
public static void qsort(Element ListHead, Element ListEnd) {
    if (ListHead == null || ListEnd == null)
        return;
    if (ListHead == ListEnd) {
        return;
    }
    //Slow游标,指向序列A的最末尾元素。
    Element Slow = ListHead;
    //Fast游标,用于遍历整个待排序列。
    Element Fast = ListHead.next;
    //TempEnd游标,总是指向Slow游标的前驱节点,递归调用时需要。
    Element TempEnd = ListHead;
    int temp;
    while (Fast != ListEnd) {
        //当前节点的值比枢轴小,进行交换。
        if (Fast.data < ListHead.data) {
            //TempEnd游标总是指向Slow的前驱。
            TempEnd = Slow;
            Slow = Slow.next;
 
            //交换Slow和Fast游标所指的元素的值
            temp = Slow.data;
            Slow.data = Fast.data;
            Fast.data = temp;
        }
        Fast = Fast.next;
    }
 
    //交换Slow游标所指的元素和枢轴元素的值,使序列成为{A} povit {B}形式
    temp = ListHead.data;
    ListHead.data = Slow.data;
    Slow.data = temp;
 
    //递归调用
    qsort(ListHead, TempEnd);
    qsort(Slow.next, ListEnd);
}

上面的代码有点问题:


struct Node 
{
	int key;
	Node* next;
	Node(int nKey, Node* pNext)
		: key(nKey)
		, next(pNext)
	{}
};


Node* GetPartion(Node* pBegin, Node* pEnd)
{
	int key = pBegin->key;
	Node* p = pBegin;
	Node* q = p->next;

	while(q != pEnd)
	{
		if(q->key < key)
		{
			p = p->next;
			swap(p->key,q->key);
		}

		q = q->next;
	}
	swap(p->key,pBegin->key);
	return p;
}

void QuickSort(Node* pBeign, Node* pEnd)
{
	if(pBeign != pEnd)
	{
		Node* partion = GetPartion(pBeign,pEnd);
		QuickSort(pBeign,partion);
		QuickSort(partion->next,pEnd);
	}
}
QuickSort(head, NULL);


  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值