来,跟我写个链表排序。
将链表排序?
对,你有什么要问我的吗?
什么类型的值?
int。
要自己写链表?
可以转换成别的容器再写吗?
这个O(N)空间,你先尝试写O(1)的。
嗯。
于是写了2分钟。
打扰一下,可以是双链表,还是只能是单链表。
你终于问我这个问题了。可以是双链表。
写完代码。
下面先附上我回来再电脑上写的完善后的代码。
#include <iostream>
using namespace std;
typedef struct lnode {
int val;
struct lnode *last;
struct lnode *next;
lnode(int newVal):val(newVal),last(nullptr),next(nullptr){}
}LNode;
LNode* init(LNode **head)
{
int val{ 0 };
LNode *tail = *head;
while (cin >> val)
{
LNode *temp = new LNode(val);
temp->last = tail;
tail->next = temp;
tail = temp;
}
return *head;
}
void printLink(LNode **head)
{
if (*head == nullptr) return;
for (LNode *cur = (*head)->next;cur != nullptr;cur = cur->next)
{
cout << cur->val<<"->";
}
cout << "NULL" << endl;
}
void delLink(LNode **head)
{
for (LNode *cur = *head;cur != nullptr;cur = cur->next)
{
LNode *temp = cur->next;
delete cur;
cur = temp;
}
*head = nullptr;
}
LNode* mySort(LNode **head)
{
//将情况考虑完整head也要不为nullptr,头指针也不为空,链表不为空
if (head == nullptr || *head == nullptr || (*head)->next == nullptr)
return *head;
LNode *cur = (*head)->next;
//链表是否有环检测
if (cur->next == nullptr) return *head;//链表为单元素
for (cur=cur->next;cur != nullptr;cur = cur->next)
{
for (LNode *pre = cur->last,*temp=cur;pre != *head;pre =temp->last)//pre变化,要画图
{
if (temp->val < pre->val)
{
//画图修改指针
pre->next = temp->next;
temp->last = pre->last;
if (temp->next)
temp->next->last = pre;
pre->last->next = temp;
temp->next = pre;
pre->last = temp;
}
else
{
break;//及时退出,减少时间
}
}
}
return *head;
}
int main()
{
LNode *head = new LNode(0);
init(&head);
cout << "原始链表:\t";
printLink(&head);
mySort(&head);
cout << "排序链表:\t";
printLink(&head);
cout << "\t\t\t\t@zem" << endl;
system("pause");
return 0;
}
运行结果:
我当时写的代码漏洞(mySort函数):
1、head指针没有检查为空的情况;
2、没有采取修改指针,而是交换了他们的值。后来才知道,这样破坏了链表,如果有个指向值为3的结点的指针,此时值被修改,那么这个指针指的再也不是正确情况。
3、循环是否能结束(链表可能有环,需要检查),我上面的代码省略了,以后可以跟面试官说明交流。
4、循环没有及时推出,或是好像写的有问题。
2016/10/26更新
用归并排序对链表进行排序(时间复杂度为O(nLogn)?):点击打开链接