O(n^2)算法里最基本和有用的insertion sort, 数组下介绍的排序方法,链表下实现。
我的初稿:
ListNode* insertionSortList(ListNode* head) {
ListNode *pNow, *pNowprev, *p, *pPrev, *temp, *temphead;
if (head == NULL || head->next==NULL) return head;
temphead = new ListNode(0);
temphead->next = head;
pNow = head->next;
pNowprev = head;
while (pNow != NULL) {
pPrev = temphead;
p = pPrev->next;
while (p != pNow) {
if (p->val <= pNow->val) {
p = p->next;
pPrev = pPrev->next;
}
else {
temp = pNow;
pNowprev->next = pNowprev->next->next;
temp->next = p;
pPrev->next = temp;
pNow = pNowprev->next;
break;
}
}
if (p == pNow) {
pNow = pNow->next;
pNowprev = pNowprev->next;
}
}
head = temphead->next;
return head;
}
1. 加了一个空表头,
2. 用了一个前指针,保持前一个位置,这种前指针在单向链表的插入删除中很常用
3. return的时候出错了,因为一开始return了head,记住,在无表头链表中,head指向的最初的单元排序后不再是开头。
优化后的写法:
ListNode *insertionSortList(ListNode *head) {
ListNode *dummy = new ListNode(0);
// 这个dummy的作用是,把head开头的链表一个个的插入到dummy开头的链表里
// 所以这里不需要dummy->next = head;
while (head != NULL) {
ListNode *temp = dummy;
ListNode *next = head->next;
while (temp->next != NULL && temp->next->val < head->val) {
temp = temp->next;
}
head->next = temp->next;
temp->next = head;
head = next;
}
return dummy->next;
}
确实简洁了许多。主要是我一开始死板的非要始终保持一条链表,完全可以像第二种,新建一个dummy node开头,然后按个插入,移动head, 始终对head进行操作。当然也需要用一个next来保持指针指向head的下一个,Java的习惯吧,也是方便记录位置。