持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第6天,点击查看活动详情。
链表中常见的算法问题
本篇将为大家介绍一些使用链表时常见的一些算法问题。
(1)如何快速倒置一个链表
在遇到这种问题时,我们可以利用头插入的特性:使用链表头插入方法为链表添加元素时,链表中元素的顺序与元素插入的顺序相反。
public void inversion(List list)
{
Node p = list.head.next; // 指针指向操作数
Node q = p.next; // 指针指向待操作数
while(p != null)
{
list.add(p);
p = q;
p = p.next;
}
}
这个方法里面,我们使用了双指针
来辅助我们执行程序。首先指针p
指向本次要操作的节点,而在进行插入后p节点
的next
属性会被修改,本该在下次插入的节点就会丢失,从而出现错误。指针q
的作用就是记录下一个该被操作的节点,让插入的顺序不会收到影响。
PS:因为我们使用的list
是一个对象,而在Java
中对象是属于引用数据类型的,所以在我们方法内对对象进行修改后,在外面的对象也会被修改,故此处不需要返回值(这根据开发需求来设置)。
(2)如何快速为链表排序
排序的方法有很多种,这里仅使用冒泡排序的方法来为链表进行排序。
public void sort(List list)
{
Node p = null;
int value = 0;
for( int i = 0; i < list.head.value; i++ )
{
p = list.head.next; // 游动指针
while(p.next != null)
{
if( p.value - p.next.value > 0)
{
value = p.value;
p.value = p.next.value;
p.next.value = value;
}
p = p.next;
}
}
}
这里我们使用冒泡排序法来为链表进行排序,冒泡排序是一种常见的排序方式,其原理是让每个元素与其下一个元素进行比较,若是当前元素大,则与其后继元素互换,直到当前元素到达结尾或是当前元素比的后继元素都小。依次循环往复,直到执行n*n
次后,就能得到一个有序的线性表。
在我们前面的设计中我们将链表的长度存储在头节点中。这里我们的外层循环就使用head.value
来确定外层循环要循环多少次;在内层循环中,当游动指针p
的next
属性指向为空时,则说明一个元素已经 “沉底” 了。
小结
本章主要讲解了链表的相关的两个算法实现。
天天学习,加速成长!
希望与各位一起变得越来越强!