您的位置:首页 > 编程语言 > C语言/C++

leetcode 链表排序

2016-04-05 17:46 393 查看
对链表排序,用归并排序。题目要求空间时间复杂度为O(nlogn),但是空间复杂度为O(1)

1.自己写的程序,时间复杂度为O(nlogn),但是空间复杂度为O(n)

用快慢指针(分别走2步和1步)找到中间节点。但是最后排序的部分,用复制将排好序的部分粘贴会原来链表中,这个方法比较笨,而且增加空间复杂度,并不满足题目要求

leetcode 提交的时候说runtime error,但自己执行是通过的,可能因为时间复杂度的原因吧,需要后期再改

void mergesort(ListNode* head, ListNode* as, ListNode* ae, ListNode* bs, ListNode* be){
vector<int> vec;
ListNode* ps = as;
ListNode* pe = be;
int i= 0;
int anum = ae - as;
int bnum = be - bs;
int ia = 0, ib = 0;
while(ia <= anum && ib <= bnum){
if(as->val <= bs->val){
vec.push_back(as->val);
as = as->next;
ia++;
}
else{
vec.push_back(bs->val);
bs = bs->next;
ib++;
}
}
while(ia <= anum){
vec.push_back(as->val);
as = as->next;
ia++;
}
while(ib <= bnum){
vec.push_back(bs->val);
bs = bs->next;
ib++;
}
int pnum = pe - ps;
int ip = 0;
while(ip <= pnum){
ps->val = vec[i++];
ps = ps->next;
ip++;
}
}

void merge(ListNode* head,ListNode* start, ListNode* end){
if(start < end){
ListNode* former=start, * latter = start;
int snum = end - start;
int latt = 0;
while(latt + 2 <= snum){
former = former->next;
latter = latter->next->next;
latt = latt + 2;
}
if(latt+1 == snum){
latter = latter->next;
}
merge(head,start,former);
merge(head,former->next,latter);
mergesort(head,start,former,former->next,end);
}
else
return;
}


2.leetcode中大神的代码,这里粘贴是为了自己以后找起来方便

它是自底向上的,归并起来。step为1,2,4,8....

/**
* merge the two sorted linked list l1 and l2,
* then append the merged sorted linked list to the node head
* return the tail of the merged sorted linked list
*/

ListNode* merge(ListNode* l1, ListNode* l2, ListNode* head){
ListNode *cur = head;
while(l1 && l2){
if(l1->val > l2->val){
cur->next = l2;
cur = l2;
l2 = l2->next;
}
else{
cur->next = l1;
cur = l1;
l1 = l1->next;
}
}
cur->next = (l1 ? l1 : l2);
while(cur->next) cur = cur->next;
return cur;
}

/**
* Divide the linked list into two lists,
* while the first list contains first n ndoes
* return the second list's head
*/

ListNode* split(ListNode *head, int n){
//if(!head) return NULL;
for(int i = 1; head && i < n; i++) head = head->next;

if(!head) return NULL;
ListNode *second = head->next;
head->next = NULL;
return second;
}

ListNode *sortList(ListNode *head) {
if(!head || !(head->next)) return head;

//get the linked list's length
ListNode* cur = head;
int length = 0;
while(cur){
length++;
cur = cur->next;
}

ListNode dummy(0);
dummy.next = head;
ListNode *left, *right, *tail;
for(int step = 1; step < length; step <<= 1){
cur = dummy.next;
tail = &dummy;
while(cur){
left = cur;
right = split(left, step);
cur = split(right,step);
tail = merge(left, right, tail);
}
}
return dummy.next;
}


其余补充的部分,对链接初始化和输出打印部分

/**
* Definition for singly-linked list.*/
struct ListNode {
int val;
ListNode *next;
ListNode(int x) : val(x), next(NULL) {}
};

ListNode* init(int a[], int n){
ListNode* q = NULL, *head = NULL;
for(int i = 0; i < n; i++){
ListNode* p = new ListNode(0);
p->val = a[i];
if(i==0){//不要忽略头结点的赋值
head = q = p;
continue;
}
q->next=p;
q = q->next;
}
q->next = NULL;
return  head;

}

void prints(ListNode* head){
while(head){
cout<<head->val<<" ";
head = head->next;
}
}

int main(int argc, const char * argv[]) {
int a[]={2,5,3,7,9,4,1,8};
//int a[]={2,1};
ListNode* head =new ListNode(0);
head=init(a,8);
ListNode* L = sortList(head);
prints(L);
return 0;
}


3.最后提交上去的版本,能运行通过且过程简单易懂,也是从别人那里看到的

/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:

void mergesort(ListNode* head, ListNode* as, ListNode* ae, ListNode* bs, ListNode* be){
vector<int> vec;
ListNode* ps = as;
ListNode* pe = be;
int i= 0;
int anum = ae - as;
int bnum = be - bs;
int ia = 0, ib = 0;
while(ia <= anum && ib <= bnum){
if(as->val <= bs->val){
vec.push_back(as->val);
as = as->next;
ia++;
}
else{
vec.push_back(bs->val);
bs = bs->next;
ib++;
}
}
while(ia <= anum){
vec.push_back(as->val);
as = as->next;
ia++;
}
while(ib <= bnum){
vec.push_back(bs->val);
bs = bs->next;
ib++;
}
int pnum = pe - ps;
int ip = 0;
while(ip <= pnum){
ps->val = vec[i++];
ps = ps->next;
ip++;
}
}

void merge(ListNode* head,ListNode* start, ListNode* end){
int hnum = end - start;
if(hnum > 0){
ListNode* former=start, * latter = start->next;
while(latter!= NULL && latter->next != NULL){
former = former->next;
if(latter->next->next == NULL)
latter = latter->next;
else
latter = latter->next->next;
}

merge(head,start,former);
merge(head,former->next,latter);
mergesort(head,start,former,former->next,end);
}
else
return;
}

ListNode* sortList(ListNode* head) {
if(head == NULL || head->next == NULL)
return head;
ListNode* p = head;
while(p->next != NULL)
p = p->next;
merge(head,head,p);
return head;
}
};
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息