在单链表上实现插入排序
2016-09-17 20:10
323 查看
问题
给单链表排序(升序排列,要保持稳定性),要求通过改变结点的next指针从而改变结点的位置,而不是只交换结点的值来使得其有序!时间复杂度为O(N^2),空间复杂度为O(1)。已知链表结点的实现如下:struct ListNode { int value; ListNode* next; ListNode(int v) : value(v), next(NULL) {} };
思路
这里很明显就是要我们做插入排序了,当然,冒泡也不是不可以,只是冒泡写起来麻烦,且性能是最差的。插入排序怎么写呢?
这个算法的思想是这样的:
1. 维护两部分,一是已排序的部分,一是待排序的部分;
2. 一开始已排序部分为NULL;
3. 每次取出待排序部分的第一个元素A,和已排序的部分逐个比较(从头往后或从后往前都可以,不过单链表只能够从头往后比较),找到第一个大于A的元素B;
4. 将A插在B的前面一个位置(这时需要注意了,如果B原来是链表头,那么A将变成新的链表头,此时要记得更新链表头指针)。
代码
#include <iostream>
#include <string>
using namespace std;
struct ListNode { int value; ListNode* next; ListNode(int v) : value(v), next(NULL) {} };
ListNode* sortList(ListNode* head) {
// 注意这样写,是不需要额外判断head是否为NULL的
ListNode *newHead = NULL, *toInsert = head;
while (toInsert != NULL) {
ListNode *current = newHead, *last = NULL, *next = toInsert->next;
// 从头往后找到第一个大于toInsert->value的元素
while (current != NULL && current->value <= toInsert->value) {
last = current;
current = current->next;
}
if (last == NULL) {
// 如果比任何已排序的数字都要小,那么就成为新的头部
toInsert->next = newHead;
newHead = toInsert;
} else {
// 否则插入到last的后面
toInsert->next = last->next;
last->next = toInsert;
}
toInsert = next;
}
return newHead;
}
// 打印链表
void display(ListNode* head) {
while (head != NULL) {
cout << head->value << ' ';
head = head->next;
}
cout << endl;
}
int main() {
ListNode* head = new ListNode(5);
head->next = new ListNode(4);
head->next->next = new ListNode(3);
head->next->next->next = new ListNode(2);
head->next->next->next->next = new ListNode(1);
display(head);
ListNode* head2 = sortList(head);
display(head2);
return 0;
}
相关文章推荐
- 作业总结
- HDU 5883 The Best Path (欧拉路或者欧拉回路)
- Leetcode :3. Longest Substring Without Repeating Characters
- 【原创】东方耀reactnative 视频22之-DrawerLayoutAndroid
- Linux/unix inode
- Arrow Dialog
- HDU5879(打表)
- 彩虹七色的RGB值
- phpstorm 2016.2 的最新破解方法(截止2016-8-1)
- 只是不想生活在最底层
- WebService(1)_WebService概述
- Java NIO使用及原理分析(二)
- Failed to load resource: the server responded with a status of 406 (Not Acceptable)
- I2S协议
- C/S模型 多线程服务器实现简单计算工作并回馈客户端
- ubuntu /etc/profile和/etc/environment的比较
- 6-文件IO-文件描述符与lseek
- 数字电路系列
- java笔记--day11--类object之hashCode() and getClass()
- Spring-2 配置bean