题意思路:
给定一个无序单链表,实现单链表的排序(按升序排序)。
方法一:利用stl和sort排序
先新建一个vector,将单链表的元素存储于vector
sort排序从小到大
将vector变成单链表
复杂度分析
时间复杂度:O(NlogN),N链表的长度,遍历链表,排序复杂度NlogN;
空间复杂度:O(N),链表存储与读取数据
代码:
/**
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
class Solution {
static bool cmp(ListNode* a,ListNode* b){
return a->val<b->val;
}
public:
/**
*
* @param head ListNode类 the head node
* @return ListNode类
*/
ListNode* sortInList(ListNode* head) {
// write code here
vector<ListNode*> node;//遍历链表元素所存储的vector
ListNode* p=head;//从头指针遍历
while(p){//若指针指向空则退出
node.push_back(p);
p=p->next;
}
sort(node.begin(),node.end(),cmp);//从小到大排序,注意cmp
for(int i=0;i<node.size()-1;i++){//构建新链表
node[i]->next=node[i+1];
}
node[node.size()-1]->next=NULL;
return node[0];//返回头指针
}
};方法二:归并排序
归并排序(Merge Sort)是建立在归并操作上的一种有效,稳定的排序算法。
该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。
将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。
若将两个有序表合并成一个有序表,称为二路归并。
复杂度分析
时间复杂度:O(NlogN),N链表的长度,遍历链表,归并排序递归复杂度NlogN;
空间复杂度:O(1),未开辟新空间
图解:
分而治之 递归处理
java代码:
/*
* public class ListNode {
* int val;
* ListNode next = null;
* }
*/
public class Solution {
/**
*
* @param head ListNode类 the head node
* @return ListNode类
*/
public ListNode sortInList (ListNode head) {
// write code here
if (head == null || head.next == null)//特判条件
return head;
ListNode i = head.next, j = head;
while (i != null && i.next != null) {// 寻找链表的中点
j = j.next;
i = i.next.next;
}
ListNode tmp = j.next;//
j.next = null;
// 递归链表中点的左右两边
ListNode l = sortInList(head);
ListNode r = sortInList(tmp);
ListNode h = new ListNode(0);
ListNode res = h;//最后用链表存储结果
// 合并 l,r两个链表
while (l != null && r != null) {//左右链表都为空则退出
//比较l和r链表中的大小
if (l.val < r.val) {//从小到大排序
h.next = l;
l = l.next;
} else {
h.next = r;
r = r.next;
}
h = h.next;
}
// 最后添加未对比的链表部分判断左链表是否为空
if(l!=null){
h.next=l;
}else h.next=r;
return res.next;
}
}

京公网安备 11010502036488号