常见的链表排序(Java版)
上篇博客中讲解了九大内部排序算法,部分算法还提供了代码实现,但是那些代码实现都是基于数组进行排序的,本篇博客就以链表排序实现几种常见的排序算法,以飨读者。
快速排序的链表实现
算法思想:对于一个链表,以head节点的值作为key,然后遍历之后的节点,可以得到一个小于key的链表和大于等于key的链表;由此递归可以对两个链表分别进行快速。这里用到了快速排序的思想即经过一趟排序能够将小于key的元素放在一边,将大于等于key的元素放在另一边。
代码实现:
//快速排序
public static void quickSort(ListNode begin, ListNode end){
if(begin == null || begin == end)
return; ListNode index = paration(begin, end);
quickSort(begin, index);
quickSort(index.next, end);
} /**
* 划分函数,以头结点值为基准元素进行划分
* @param begin
* @param end
* @return
*/
public static ListNode paration(ListNode begin, ListNode end){
if(begin == null || begin == end)
return begin; int val = begin.val; //基准元素
ListNode index = begin, cur = begin.next; while(cur != end){
if(cur.val < val){ //交换
index = index.next;
int tmp = cur.val;
cur.val = index.val;
index.val = tmp;
}
cur = cur.next;
} begin.val = index.val;
index.val = val; return index;
}
归并排序的链表实现
算法思想:单链表与数组相比只能顺序访问每个元素,因此在使用二路归并排序时关键在于找到链表的中间结点将链表一分为二:可以利用快慢指针同时遍历单链表,当步长为2的指针指向链表最后一个结点或者最后一个结点的下一个结点时,步长为1的指针即指向链表的中间结点。然后是两个有序单链表的合并问题。时间复杂度为O(N*logN),空间复杂度为O(1)。
代码实现:
//归并排序
public static ListNode mergeSort(ListNode head){
if(head == null || head.next == null) //空链表或者只有单个结点
return head;
ListNode slow = head, fast = head.next; while(fast != null && fast.next != null){ //使用快慢指针寻找中间 结点
slow = slow.next; fast = fast.next;
if(fast.next != null)
fast = fast.next;
} ListNode ptr1 = slow.next;
slow.next = null; ListNode tmp1 = mergeSort(head);
ListNode tmp2 = mergeSort(ptr1);
return merge(tmp1, tmp2);
} public static ListNode merge(ListNode start1, ListNode start2){
ListNode header = new ListNode(-1);
ListNode pre = header; ListNode ptr1 = start1, ptr2 = start2;
while(ptr1 != null && ptr2 != null){
if(ptr1.val <= ptr2.val){
pre.next = ptr1;
pre = ptr1;
ptr1 = ptr1.next;
}else{
pre.next = ptr2;
pre = ptr2;
ptr2 = ptr2.next;
}
}
while(ptr1 != null){
pre.next = ptr1;
pre = ptr1;
ptr1 = ptr1.next;
} while(ptr2 != null){
pre.next = ptr2;
pre = ptr2;
ptr2 = ptr2.next;
} return header.next; }
冒泡排序的链表实现
算法思想:依次比较相邻的结点,如果是逆序的就交换两个结点
代码实现:
//冒泡排序
public static ListNode bubbleSort(ListNode head){
if(head == null || head.next == null) //链表为空或者仅有单个结点
return head; ListNode cur = null, tail = null; cur = head; while(cur.next != tail){
while(cur.next != tail){
if(cur.val > cur.next.val){
int tmp = cur.val;
cur.val = cur.next.val;
cur.next.val = tmp;
}
cur = cur.next;
} tail = cur; //下一次遍历的尾结点是当前结点(仔细琢磨一下里面的道道)
cur = head; //遍历起始结点重置为头结点
} return head; }
先写这几种吧,想起来再更。。。
常见的链表排序(Java版)的更多相关文章
- c++复杂桶排序Java版
c++复杂桶排序Java版 题目和我的前几个排序一样 这次是Java版的 代码 + 注释 package com.vdian.qatest.supertagbiz.test.niu; /** * Cr ...
- 算法练习5---快速排序Java版
基本思想:通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成 ...
- 常见机试题分析Java版
1. 操作系统任务分为系统任务和用户任务两种.其中,系统任务的优先级<50,用户任务的优先级>=50且<=255.优先级大于255的为非法任务,应予以剔除.现有一任务队列task[] ...
- 选择排序Java版
package dataStructureAlgorithmReview.day01; import java.util.Arrays; /** * * @author shundong * */ p ...
- 南阳ACM 题目8:一种排序 Java版
一种排序 时间限制:3000 ms | 内存限制:65535 KB 难度:3 描述 现在有很多长方形,每一个长方形都有一个编号,这个编号可以重复:还知道这个长方形的宽和长,编号.长.宽都是整数:现 ...
- 算法练习4---冒泡排序java版
冒泡排序的基本思想:在要排序的一组数中,对当前还未排好序的范围内的全部数,自上而下对相邻的两个数依次进行比较和调整,让较大的数往下沉,较小的往上冒.即:每当两相邻的数比较后发现它们的排序与排序要求相反 ...
- 算法练习1---桶排序java版
今天复习了桶排序. 例如现在有满分为10分的试卷,学生得分分别为2,8,5,3,5,7,现在要给这些分数按照从大到小输出,使用桶排序的思想:有11个桶,每个桶有一个编号,编号从0-10,每出现一个分数 ...
- 剑指offer第二版面试题5:从尾到头打印链表(JAVA版)
题目描述: 输入一个链表,从尾到头打印链表每个节点的值.返回新链表. import java.util.Stack; //定义链表结构 class ListNode { int value; List ...
- 《剑指offer》面试题13 在O(1)时间删除链表节点 Java版
这道题的关键是知道找到尾节点的前一个节点必须遍历,而且这样做了之后总的时间复杂度还是O(1),以及如何不破坏链表删除一个已知节点 public ListNode delete(ListNode hea ...
随机推荐
- PCI9054 学习小结
PCI的基本协议这里就不介绍了,因为一般的芯片协议都是集成好的,我只需要大体了解就行,不需要做芯片,我感觉就不需要太了解协议. 这里讲解是基于PLX 的9054(9052)芯片为基础的,本人只是入门, ...
- linux驱动---用I/O命令访问PCI总线设备配置空间
PCI总线推出以来,以其独有的特性受到众多厂商的青睐,已经成为计算机扩展总线的主流.目前,国内的许多技术人员已经具备开发PCI总线接口设备的能 力.但是PCI总线的编程技术,也就是对PCI总线设备的操 ...
- CSDN博客添加量子恒道统计代码步骤
CSDN博客添加量子恒道统计代码步骤. 1. 去量子恒道网站统计 注册账户: 2. 添加已有的CSDN博客地址: 3. 添加博客后恒道代码里面会给你一个JavaScript脚本,记下里面的一串数字: ...
- html标签自带样式总结
一.html标签自带样式 head { display:none; } body { margin:8px; line-height:1.12; } button, textarea, input, ...
- OpenStack_I版 3.glance部署
存储镜像path 默认镜像不存储在本地,一般放在swift对象存储或Cinder块存储里 glance安装 拷贝配置文件到/ect下,并新建配置目录,日志目 ...
- Dijkstra算法与Bellman - Ford算法示例(源自网上大牛的博客)【图论】
题意:题目大意:有N个点,给出从a点到b点的距离,当然a和b是互相可以抵达的,问从1到n的最短距离 poj2387 Description Bessie is out in the field and ...
- JavaScript的作用域详解。
首先讲原理,大家都知道JS是逐行执行,首先进入作用域只有有两种方式: 1.当看到script标签的时候,进入到作用域,也就是内置的<script></script> ...
- type="submit" button的用法
原因:关于页面刷新,或者点击某个按钮,开始能现实值,但几秒钟就会刷新掉的原因,这是因为sunmit 和button自带刷新属性,所以说少用就好,或者用returen fales 来断掉接下来的操作,当 ...
- github上的文件比对
Skip to content This repository Pull requests Issues Marketplace Explor ...
- NOIP2017总结
NOIP2017 总结 今年又炸飞天了,day1T1T2加起来不到100分,T3只有10分--怕真的要AFO了. 和去年一模一样day1炸飞天,day2虽然发挥正常但也无力回天 day1 Day1T1 ...