选择排序和插入排序
选择排序
选择排序:选择排序的思路是从一组元素中逐次选择最大的元素,放在无序元素末端,具体的实现过程如下图所示。因此选择排序需要存在以下几个接口:
1.selectMax(p,n):从节点p开始,在节点p前n个节点中(不包括节点p)选择一个节点返回。
<pre>
public static ListNode selectMax(ListNode p, int n) {
ListNode max = p;
while(0 < n--) {
if(p.data <= p.nexNode.data) {
p = p.nexNode;
max = p;
}
}
return max;
}
</pre>
2.insertBefore(tail,max):在尾部节点tail前插入max节点
<pre>
public static ListNode insertBefore(ListNode tail, ListNode max) {
tail.preNode.nexNode = max;
max.nexNode = tail;
max.preNode = tail.preNode;
tail.preNode = max;
return max;
}
</pre>
3.选择排序:
<pre>
public class LinkedList {
public static void main(String[] args) {
//创建一个链表node1->node2->node3->node4->node5
ListNode head = new ListNode();
ListNode node1 = new ListNode(10);
ListNode node2 = new ListNode(8);
ListNode node3 = new ListNode(9);
ListNode node4 = new ListNode(5);
ListNode node5 = new ListNode(2);
ListNode tail = new ListNode();
head.nexNode = node1;
node1.preNode = head;
node1.nexNode = node2;
node2.preNode = node1;
node2.nexNode = node3;
node3.preNode = node2;
node3.nexNode = node4;
node4.preNode = node3;
node4.nexNode = node5;
node5.preNode = node4;
node5.nexNode = tail;
tail.preNode = node5;
tranvers(head);
System.out.println("*************");
head = selectionSort(head,tail,5);
tranvers(head);
}
public static ListNode selectionSort(ListNode head, ListNode tail, int n) {
ListNode last = tail;
while(1 < n--) {
ListNode max = selectMax(head.nexNode, n);
int data = remove(max);
last = insertBefore(last, max);
}
return head;
}
</pre>
插入排序
插入排序始终将序列分成两个部分:第一部分是sorted,第二部分是unsorted。插入排序的主要思想是将unsorted部分的第一个元素插入到sortred部分,使sorted部分仍然是有序的。主要思路如下图所示:
- insertBefore(tail, max): 在tail节点前插入max节点,返回max节点
<pre>
public static ListNode insertBefore(ListNode tail, ListNode max) {
tail.preNode.nexNode = max;
max.nexNode = tail;
max.preNode = tail.preNode;
tail.preNode = max;
return max;
}
</pre>
2.selectMax(data, n, p):在p节点的前n个节点中找到数值不大于data的第一个节点的前一个节点
<pre>
public static ListNode selectMax(int data, int n, ListNode p) {
//在p之前n个结点中找到不大于data的那个节点的前一个节点
ListNode tail = p;
while(0 < n--) {
if(data <= tail.preNode.data) {
tail = tail.preNode;
}else {
return tail;
}
}
return tail;
}
</pre>
3.remove(p): 删除p节点并且返回p节点存储的数值
<pre>
public static int remove(ListNode p) {
//删除p节点,返回p节点的数值
int data = p.data;
if (p.nexNode == null) {
p.preNode.nexNode = null;
}else {
p.preNode.nexNode = p.nexNode;
p.nexNode.preNode = p.preNode;
}
return data;
}
</pre>
4.tanvers(head):遍历表头为head的链表
<pre>
public static void tranvers(ListNode head) {
ListNode p = head;
while(p != null) {
System.out.println(p.data);
p = p.nexNode;
}
}
rs(ListNode head) {
ListNode p = head;
while(p != null) {
System.out.println(p.data);
p = p.nexNode;
}
}
</pre>
5.main方法:
<pre>
public class insertSort {
public static void main(String[] args) {
ListNode head = new ListNode();
ListNode node1 = new ListNode(10);
ListNode node2 = new ListNode(8);
ListNode node3 = new ListNode(9);
ListNode node4 = new ListNode(5);
ListNode node5 = new ListNode(11);
ListNode tail = new ListNode();
head.nexNode = node1;
node1.preNode = head;
node1.nexNode = node2;
node2.preNode = node1;
node2.nexNode = node3;
node3.preNode = node2;
node3.nexNode = node4;
node4.preNode = node3;
node4.nexNode = node5;
node5.preNode = node4;
node5.nexNode = tail;
tail.preNode = node5;
tranvers(head);
System.out.println("*************");
insertSort(head,5);
tranvers(head);
}
public static void insertSort(ListNode head, int n) {
ListNode p = head.nexNode;
int i = 1;
while(i < n) {
if(p.data <= p.nexNode.data) {
System.out.println(p);
p = p.nexNode;
}else {
ListNode insertNode = p.nexNode;
ListNode tail = selectMax(insertNode.data,i,insertNode);
int data = remove(insertNode);
ListNode max =insertBefore(tail, insertNode);
}
i++;
}
}
}
</pre>