上一节写了单向链表的实现,现在来写一下单向链表的排序
上一节写的单向链表按照先进后出的原则实现的单向链表,这一节依然按照先进后出的原则实现链表。
实现链表的代码在上一节,这里就只按照冒泡排序的方法排序一个链表,顺便可以学习一下冒泡排序。
1.冒泡排序
冒泡排序是一种比较简单的排序算法。它重复的走访需要排序的数列,每一次比较相邻的元素,如果元素排列部不符合我们的要求(从小到大或从大到小的顺序)就将这两个元素的位置调换。直到所有的元素都满足要求不需要再调换位置了,排序完成。
用图来解释冒泡排序比较清晰,我来画一幅(从大到小排序)。第一次循环完成的比较图,后面的循环原理是一样的。每次循环都会把最小的元素选出来,第一次循环会将最小的元素放到最后面。
冒泡排序的java代码实现:
package com.yushen.linkedlist;
public class BlueSort {
public static void main(String[] args) {
// 构建数组
int[] arr = { 3, 4, 5, 2, 1 };
// 临时存放元素
int temp = 0;
// 最外层循环代表循环次数
for (int i = 1; i < arr.length; i++) {
// 内层循环将相邻的两个元素进行比较
for (int j = 0; j < arr.length - i; j++) {
if (arr[j] < arr[j + 1]) {
temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
}
// 遍历输出数组元素
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i] + " ");
}
}
}
2.冒泡排序单向链表
链表的冒泡排序比较的是节点中数值
代码如下:
package com.yushen.linkedlist;
public class BlueSort {
public static void main(String[] args) {
// 创建一个链表
LinkedList linkedList = new LinkedList();
linkedList.add(3);
linkedList.add(4);
linkedList.add(5);
linkedList.add(2);
linkedList.add(1);
// 获取链表长度
int length = linkedList.getLength();
// 临时存放
int temp = 0;
// 冒泡排序(按照从大到小的顺序排序)
for (int i = 1; i < length; i++) {
for (int j = 0; j < length - i; j++) {
// 获取当前需要比较的两个节点
Node node1 = linkedList.get(j);
Node node2 = linkedList.get(j + 1);
if (null != node1 && null != node2) {
// 比较节点中的数值大小
if (node1.data < node2.data) {
// 不符合需要的顺序就进行交换位置
temp = node1.data;
node1.data = node2.data;
node2.data = temp;
}
}
}
}
for (int i = 0; i < linkedList.getLength(); i++) {
System.out.print(linkedList.get(i).data + " ");
}
}
}
3 附上链表代码:
节点类:
package com.yushen.linkedlist;
/**
* 单向链表
*
* @author yushen
*
*/
public class Node {
public Node next;//指向后继节点的指针
public int data;
public Node(int data) {
this.data = data;
this.next = null;
}
}
链表类:
package com.yushen.linkedlist;
/**
* 对单向链表的操作
*
* @author Administrator
*
*/
public class LinkedList {
// 第一次调用,将头节点置空
Node head = null;
/**
* 寻找指定data的节点
*
* @param linkedList
* 一个链表
* @param data
* 要寻找的数据
* @return
*/
public Node select(int data) {
// 从头节点开始
Node node = head;
// 只要node节点不为空且node节点的data不是要找的数据,就一直往后找
while (null != node && node.data != data) {
node = node.next;
}
return node;
}
/**
* 对链表进行添加元素
*/
public void add(int data) {
// 创建节点
Node newNode = new Node(data);
if (null == head) {
// 如果头节点为空,则当前的节点为头节点
head = newNode;
return;
}
// 当前头节点不为空,则将要添加的节点放到最前
newNode.next = head;
head = newNode;
}
/**
* 向链表指定位置进行添加元素
*
* @param index
* 指定添加元素的位置索引
* @param data
* 要添加的元素
*/
public void add(int index, int data) {
// 创建节点
Node newNode = new Node(data);
if (null == head) {
// 如果头节点为空,则当前的节点为头节点
head = newNode;
return;
}
// 如果索引是0,添加元素为头元素
if (index == 0) {
newNode.next = head;
head = newNode;
return;
}
// 遍历当前链表
for (int i = 1; i < this.getLength(); i++) {
if (i == index) {
// 当前元素的前一个元素的后继元素指向要插入的节点元素
this.get(i - 1).next = newNode;
// 要插入的节点元素的后继元素指向当前元素
newNode.next = this.get(i);
break;
}
}
}
/**
* 删除链表元素
*
* @param data
*/
public void delete(int data) {
// 先找到要删除的节点
Node node = this.select(data);
if (null == node) {
// 要删除的节点不存在
System.out.println("error:node do not exits");
return;
}
// 将找到的node节点删除
Node tempNode = head;
// 如果头节点就是要删除的元素
if (head.data == data) {
head = head.next;
return;
}
while (null != tempNode && tempNode.next.data != node.data) {
tempNode = tempNode.next;
}
tempNode.next = node.next;
}
/**
* 返回链表的长度
*
* @return
*/
public int getLength() {
int length = 0;
Node node = head;
while (null != node) {
length++;
node = node.next;
}
return length;
}
/**
* 返回指定位置的元素
*
* @param linkedList
* @param index
* @return
*/
public Node get(int index) {
Node node = head;
int length = 0;
while (null != node && length != index) {
length++;
node = node.next;
}
return node;
}
/**
* 替换指定位置的元素
*
* @param index
* 替换元素的位置索引
* @param data
* 新元素
*/
public void replace(int index, int data) {
Node newNode = new Node(data);
if (index == 0) {
head = newNode;
return;
}
// 遍历当前链表
for (int i = 1; i < this.getLength(); i++) {
if (i == index) {
newNode.next = this.get(i).next;
this.get(i - 1).next = newNode;
break;
}
}
}
}