待字闺中之快排单向链表;leetcode之Sort List
题目来源。待字闺中。原创@陈利人
。欢迎大家继续关注微信公众账号“待字闺中”
分析:思路和数据的高速排序一样,都须要找到一个pivot元素、或者节点。
然后将数组或者单向链表划分为两个部分。然后递归分别快排。
针对数组进行快排的时候,交换交换不同位置的数值。在分而治之完毕之后,数据就是排序好的。那么单向链表是什么样的情况呢?除了交换节点值之外。是否有其它更好的方法呢?能够改动指针,不进行数值交换。这能够获取更高的效率。
在改动指针的过程中。会产生新的头指针以及尾指针,要记录下来。在partition之后,要将小于pivot的的部分、pivot、以及大于pivot的部分又一次串起来成为一个singly
linked list。
在partition时。我们用最后的节点作为pivot。当我们扫描链表时,假设节点值大于pivot,将节点移到尾部之后;假设节点小于。保持不变。
在递归排序时。我们先调用partition将pivot放到正确的为止并返回pivot,然后。递归左边。递归右边。最后在合成一个单链表。
详细代码例如以下:
#include <iostream>
#include <map>
#include <vector>
#include <assert.h>
using namespace std; struct node
{
int data;
struct node* next;
node(int x):data(x),next(NULL){}
}; node* partition(node* start,node* end,node** newHead,node** newEnd)
{
node* provit = end,*tmp = NULL,*pre = NULL;
while(start != provit)
{
if(start->data > provit->data)
{
tmp = start->next;
if(pre)pre->next = tmp;
start->next = NULL;
end->next = start;
end = start;
start = tmp;
}
else
{
if(*newHead == NULL)*newHead = start;
pre = start;
start = start->next;
}
}
if(*newHead == NULL)*newHead = provit;
*newEnd = end;
return provit;
}
node* GetTail(node* head)
{
if(head == NULL)return NULL;
while(head->next != NULL)head = head->next;
return head;
}
node* QuickSort(node* head,node* end)
{
if(head == NULL || head == end)return head;
node* newHead = NULL,*newEnd = NULL;//此处不能用二维指针。不然partition调用*newHead解引用时会出错
node* provit = partition(head,end,&newHead,&newEnd);
if(newHead != provit)
{
node* tmp = newHead;
while(tmp->next != provit)tmp = tmp->next;
tmp -> next = NULL;
newHead = QuickSort(newHead,tmp);
tmp = GetTail(newHead);
tmp->next = provit;
}
if(provit != newEnd)
{
provit->next= QuickSort(provit->next,newEnd);
}
return newHead;
}
void QuickSort(node** head)
{
if(head == NULL)return;
*head = QuickSort(*head,GetTail(*head));
}
void printLink(node* head)
{
while(head != NULL)
{
cout << head->data <<" ";
head = head->next;
}
cout << endl;
}
int main()
{
int n,i,value;
node* head,*q;
cin >> n;
for(i=0;i<n;i++)
{
cin >> value;
if(i == 0)
{
head = new node(value);
q = head;
}
else
{
node* p = new node(value);
q->next = p;
q = p;
}
}
printLink(head);
QuickSort(&head);
printLink(head);
return 0;
}
leetcode之
Sort List
Sort
a linked list in O(n log n)
time using constant space complexity.
该题用上面的方法会超时,能够使用归并排序
class Solution {
public:
ListNode *sortList(ListNode *head)
{
if(!head || !head->next)return head;
ListNode* fast = head -> next -> next;//至少有两个节点
ListNode* slow = head;
while(fast)
{
fast = fast->next;
slow = slow->next;
if(!fast)break;
fast = fast->next;
}
ListNode* p = slow -> next;
slow -> next = NULL;
ListNode* q = sortList(head);
p = sortList(p);
head = NULL;
ListNode* tail = NULL;
while(q && p)
{
if(q->val > p->val)
{
if(!head)head = tail = p;
else
{
tail->next = p;
tail = tail->next;
}
p = p->next;
}
else
{
if(!head)head = tail = q;
else
{
tail->next = q;
tail = tail->next;
}
q = q->next;
}
}
if(p)
{
if(!head)head = tail = p;
tail->next = p;
}
if(q)
{
if(!head)head = tail = q;
else tail->next = q;
}
return head;
}
};
待字闺中之快排单向链表;leetcode之Sort List的更多相关文章
- 链表快排 & 基于链表的排序
以前只知道链表做插入(朴素.非二分)排序挺方便的.现在知道了(单)链表进行快速排序也是很好的(只是跟一般的快排的方式不一样). 参考: http://blog.csdn.net/otuhacker/a ...
- Java常见的几种排序算法-插入、选择、冒泡、快排、堆排等
本文就是介绍一些常见的排序算法.排序是一个非常常见的应用场景,很多时候,我们需要根据自己需要排序的数据类型,来自定义排序算法,但是,在这里,我们只介绍这些基础排序算法,包括:插入排序.选择排序.冒泡排 ...
- 结构体快排回顾(sort)
一般来说,我做竞赛的时候排序一般用快排 很快很方便 普通sort(从小到大) sort(a,a+n); 直接贴一段代码吧,包含了vector,sort,结构体等简单东西综合 #include < ...
- C语言实现单向链表及其各种排序(含快排,选择,插入,冒泡)
#include<stdio.h> #include<malloc.h> #define LEN sizeof(struct Student) struct Student / ...
- 63.如何对单链表进行快排?和数组快排的分析与对比[quicksort of array and linked list]
[本文链接] http://www.cnblogs.com/hellogiser/p/quick-sort-of-array-and-linked-list.html [题目] 单链表的特点是:单向. ...
- java链表实现快排
链表文件 package sort; public class SqList { public int LIST_INIT_SIZE = 8;//链表的原始大小 private int I ...
- LeetCode 75. Sort Colors (颜色分类):三路快排
Given an array with n objects colored red, white or blue, sort them in-place so that objects of the ...
- leetcode 75 Sort Colors 计数排序,三路快排
解法一:计数排序:统计0,1,2 的个数 时间复杂度:O(n) 空间复杂度:O(k) k为元素的取值范围, 此题为O(1) class Solution { public: void sortC ...
- LeetCode 75. Sort Colors (python一次遍历,模拟三路快排)
LeetCode 75. Sort Colors (python一次遍历,模拟三路快排) 题目分析: 本题需要实现数字只包含0,1,2的排序,并且要求一次遍历. 由于只用把数字隔离开,很容易想到快排的 ...
随机推荐
- 高性能 Socket 组件 HP-Socket v3.2.1 正式公布
HP-Socket 是一套通用的高性能 TCP/UDP Socket 组件,包括服务端组件.client组件和 Agent 组件,广泛适用于各种不同应用场景的 TCP/UDP 通信系统,提供 C/C+ ...
- java获取路径(转)
1.利用System.getProperty()函数获取当前路径:System.out.println(System.getProperty("user.dir"));//user ...
- FPGA三段式状态机的思维陷阱
用三段式描述状态机的好处,国内外各位大牛都已经说的很多了,大致可归为以下三点: 1.将组合逻辑和时序逻辑分开,利于综合器分析优化和程序维护; 2.更符合设计的思维习惯; 3.代码少,比一段式状态机更简 ...
- C#的几种写文件方法
C#写文件处理操作在很多的开发项目中都会涉及,那么具体的实现方法是什么呢?这里向大家介绍三大方法,希望对你在开发应用中有所启发. 首先C#写文件处理操作必须先导入命名空间:using System.I ...
- IDEA是如何导入项目的,及启动导入项目遇到的问题:无法加载主类的一连串问题
1.启动报错误: 找不到或无法加载主类 org.spring.springboot.Application 可能在工程下面有多个module,然后,module里面的iml配置文件不止一个,删除留主的 ...
- DateNavigator
<Border BorderThickness="1,1,1,1" BorderBrush="Black" Grid.Column="1&quo ...
- IT运维流程 — ITIL
导读 在IT运维中,最有名也是最实用的流程就是ITIL.说到这里,我想大家都有过实施ITIL痛苦的经历,一定会有人说:我们没有办法实施ITIL. 问:ITIL是什么? 答:ITIL即IT基础架构库(I ...
- window系统下调度数据库类型资源库中的kettle job
已经存在kettle的一个资源库enfo,在目录/works/wxj下面有一个job (testmailsuccess.kjb)如何实现手工在kettle外部执行此job和让系统每天定时的调用此job ...
- winform暴走表情制作器
c# winform暴走表情制作器,项目工程下载地址:项目下载地址 程序运行截图: 部分代码:获取鼠标所在的图片中坐标 private void pictureBox1_MouseDown(objec ...
- Android 四大组件之 Service(一)
Service是Android中四大组件之一,在Android开发中起到非常重要的作用,它运行在后台,不与用户进行交互. 1.Service的继承关系: java.lang.Object → andr ...