選擇排序和插入排序
選擇排序
選擇排序:選擇排序的思路是從一組元素中逐次選擇最大的元素,放在無序元素末端,具體的實現過程如下圖所示。因此選擇排序需要存在以下幾個接口:
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>