链表的选择排序
链表的选择排序
问题重述:
给定一个无序单链表的头节点head,实现单链表的选择排序
要求:额外空间复杂度为O(1)
问题分析:
解法:
选择排序
解题:
代码:
// 如果没有限定空间复杂度的话,可以直接将结点放进数组中,然后在数组中进行选择排序,排序完成后在将结点联结起来
/**
* 实现链表的选择排序
* @param head
* @return
*/
public static Node selectSort(Node head) {
// 首先定义几个结点用于操作
// 定义一个结点用于记录当前最小结点,以及当前结点的前一个结点
Node smallPre = null;
Node small = null;
// 定义两个结点用于记录当前结点信息
Node tail = null;
Node cur = head;
// 对链表进行循环
while(cur != null) {
small = cur;
// 获取最小结点的前一个结点
smallPre = getSmallestPreNode(cur);
// 删除最小节点
if(smallPre != null) {
small = smallPre.next;
smallPre.next = small.next;
}
// 将最小节点添加到tail中去
if(tail == null) {
head = small;
}else {
tail.next = small;
}
tail = small;
// 更新cur,如果当前结点是最小值,那么从下一个结点开始,否则,当前结点继续和后面的结点进行比较
cur = (cur == small ? cur.next : cur);
}
return head;
}
/**
* 给定一个链表的头节点,找到当前链表中的最小值,并且返回该节点的前一个结点
* @param head
* @return
*/
public static Node getSmallestPreNode(Node head) {
// 我们需要一个结点来保存最小结点的前一个结点
Node smallPre = null;
// 一个结点用于比较最小结点,最开始是第一个结点为最小值
Node small = head;
// 用于记录当前节点的前一个结点
Node pre = head;
// 记录当前结点,为了保持链表的结构
Node cur = head.next;
while(cur != null) {
// 如果当前结点的值小于最小结点的值,更新最小节点
if(cur.value < small.value) {
// 更新最小结点以及最小节点的前一个结点
smallPre = pre;
small = cur;
}
pre = cur;
cur = cur.next;
}
return smallPre;
}
代码解析:链表默认是没有排序的,我们先找到链表中的最小值,以该值作为链表的头节点,(如果本来就是头节点,那么就不需要修改),此时只需要将tail更新为最小值,然后已经排序好了的链表就不动,对后续没有排序的结点进行查找,最小值连接到tail后方。
总结:
选择排序:首先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置。再从剩余未排序元素中继续寻找最小(大)元素,然后放到已排序序列的末尾。重复第二步,直到所有元素均排序完毕
// 选择排序的流程
int[] array = new int[10];
for(int i = 0;i < array.length;i++){
// 记录当前尾部
int res = i;
for(int j = i;j < array.length-i;j++){
if(array[j] < res){
// 获取未排序部分中的最小(大)值
res = j;
}
}
// 将最小(大)值放到尾部
int temp = array[i];
array[i] = array[j];
array[j] = temp;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】