单链表快速排序,不直接交换值,不使用额外链表空间,原地交换节点
做了数组的快速排序后,想着试一下单链表的快速排序。菜鸟一个 还请指正 单链表快速排序,不直接交换值,不使用额外链表空间,原地交换节点。 单链表快速排序三种解决办法 (1) 直接交换值,相对简单 (2) 额外维护两个链表,用于存放大于基点的节点和小于基点的基点 最后链接 (3) 不直接交换值,不使用额外链表空间,原地交换节点。较为复杂 我的思路: 分区函数中维护多个指针 index: 用于表示基点的正确位置,维护index左边都是小于基点的值 pre : index的前驱节点,原地交换节点时使用,同时作为函数返回值返回,表示左区间的结束节点 curr : 用于遍历节点 prec : curr的前驱节点,原地交换节点时使用, 分区函数返回值: next : 基点的下一个节点,作为函数返回值返回,表示右区间的开始节点 left : 新的开始节点,因为链表经过分区操作后,开始节点不在是原先的节点 right: 新的结束节点,因为链表经过分区操作后,结束节点不在是原先的节点
作者:pang-hou-n 链接:https://leetcode-cn.com/problems/sort-list/solution/dan-lian-biao-kuai-su-pai-xu-bu-zhi-jie-gpi6v/ 来源:力扣(LeetCode) 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
func sortList(head *ListNode)*ListNode{
preHead:=&ListNode{
-1,
head,
}
right:=head
for right.Next!=nil{
right=right.Next
}
preHead=NodesQuicSort(preHead,head,right)
return preHead.Next
}
func NodesQuicSort(preHead,left,right *ListNode)*ListNode{
if(left!=right){
mid:=left
left,pre,next,right:=partition_02(left,right)
preHead.Next=left
NodesQuicSort(preHead,left,pre)
NodesQuicSort(mid,next,right)
}
return preHead
}
func partition_02(left,right *ListNode)(*ListNode,*ListNode,*ListNode,*ListNode){
povitNode:=left
index:=left.Next
curr:=index
prec:=left
pre:=povitNode
end:=right.Next
for curr!=end{
if curr.Val<povitNode.Val{
if curr!=index{
temp:=index.Next
index.Next=curr.Next
curr.Next=temp
pre.Next=curr
pre=pre.Next
prec.Next=index
prec=index
temp=index.Next
index=curr.Next
curr=temp
}else{
pre=index
index=index.Next
prec=curr
curr=curr.Next
}
}else{
prec=curr
curr=curr.Next
}
}
right=prec
if pre!=povitNode{
left=povitNode.Next
povitNode.Next=index
pre.Next=povitNode
}
next:=povitNode.Next
if(povitNode.Next==end){
right=povitNode
next=right
}
return left,pre,next,right
}
|