zl程序教程

您现在的位置是:首页 >  后端

当前栏目

无序链表排序_双向链表排序算法

链表算法排序 双向 无序
2023-06-13 09:14:59 时间

需求

给定一个无序的链表,输出有序的链表。

分析

链表排序比较特殊,由于不连续的性质,所以在进行排序的时候要引入外排思想,因此归并排序或者多路归并就成为了排序的选择。 归并排序分为拆分、合并两个阶段: 1. 拆分 需要找出链表中间节点,并根据中间节点拆分成两个独立的链表,递归直到拆分成单个节点为止。 2. 合并 由于此时每个链表都为单节点,所以对于拆分的两个子链表实质上是有序链表合并问题。

代码

下面是示例代码

    private class Node {
int value;
Node next;
}
private Node getRandomList(int length)
{
Node node = new Node();
int randomNum = (int) ((Math.random() * 100) % 100);
node.value = randomNum;
Node head = node;
for(int i = 0; i < length; i++)
{
randomNum = (int) ((Math.random() * 100) % 100);
Node temp = new Node();
temp.value = randomNum;
node.next = temp;
node = temp;
}
return head;
}
private Node getMiddleNode(Node head)
{
Node index1 = head;
Node index2 = head;
while(index2.next != null && index2.next.next != null)
{
index1 = index1.next;
index2 = index2.next.next;
}
return index1;
}
private Node mergeSort(Node head)
{
if(head.next == null)
return head;
Node middelNode = getMiddleNode(head);
Node head1 = head;
Node head2 = middelNode.next;
middelNode.next = null;
head1 = mergeSort(head1);
head2 = mergeSort(head2);
Node currenthead = mergeSequentialList(head1, head2);
return currenthead;
}
private Node mergeSequentialList(Node head1, Node head2)
{
if(head1 == null)
return head2;
if(head2 == null)
return head1;
Node currentNode = null;
if(head1.value < head2.value)
{
head1.next = mergeSequentialList(head1.next, head2);
currentNode = head1;
}
else
{
head2.next = mergeSequentialList(head1, head2.next);
currentNode = head2;
}
return currentNode;
}
private int outputListValue(Node list, StringBuffer bf) {
// TODO Auto-generated method stub
int i = 0;
while(list.next != null)
{
bf.append(list.value + "-");
i++;
list = list.next;
}
return i;
}
public void main()
{
Node list = getRandomList(50);
list = mergeSort(list);
StringBuffer bf = new StringBuffer();
int count = outputListValue(list, bf);
String result = bf.toString();  
}

复杂度

对于中间节点的查找,可以使用两指针不同步调方式,查找的时间复杂度为O(n)。 对于两个有序子链表合并,递归深度为最短链表深度,时间复杂度为O(n)。 由于归并排序会调用logn次,所以最终的时间复杂度为(2n)logn = O(nlogn)。

总结

无序链表排序考察的知识点比较多,首先要深刻理解归并排序的思想与应用场景,其次算法中也运用到了链表中间节点查找、两个有序链表归并等单算法,并且也要考虑单算法其中的细节。整体算法难度比较难。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/183150.html原文链接:https://javaforall.cn