逆置/反转单链表
同从尾到头打印单链表一样,我们可以分别采用递归和栈来进行操作。
单链表排序(冒泡排序&快速排序)
冒泡排序:对相邻的两个节点的值进行比较,若是逆序则交换其值。
package com.struct.interview_question.list_interview_question.listsort;
public class BubbleSort {
public ListNode bubbleSort(ListNode head) {
if (head == null || head.nextNode == null) {
return head;
}
ListNode current = null;
ListNode tail = null;
current = head;
while(current.nextNode!=tail){
while(current.nextNode!=tail){
if(current.data>current.nextNode.data){
int temp = current.data;
current.data = current.nextNode.data;
current.nextNode.data = temp;
}
current = current.nextNode;
}
tail = current;
current = head;
}
return head;
}
}
@Test
public void test_BubbleSort(){
ListNode listNode = new ListNode(8);
listNode.nextNode = new ListNode(4);
listNode.nextNode.nextNode = new ListNode(2);
listNode.nextNode.nextNode.nextNode = new ListNode(5);
BubbleSort bubbleSort = new BubbleSort();
ListNode head = bubbleSort.bubbleSort(listNode);
while (head!=null){
System.out.print(head.data+"->");
head = head.nextNode;
}
}
快速排序:以一个链表的头节点的值作为基准值,依次遍历节点,
即可得到一个小于基准值的链表和一个大于基准值的链表,
我们可以采用递归对大于和小于基准值的两个链表也采用快速排序。
package com.struct.interview_question.list_interview_question.listsort;
public class QuickSort {
public ListNode quickSort(ListNode begin, ListNode end) {
if (begin == null || begin == end) {
return begin;
}
ListNode index = divide(begin, end);
quickSort(begin, index);
quickSort(index.nextNode, end);
return begin;
}
public static ListNode divide(ListNode begin, ListNode end) {
if (begin == null || begin == end) {
return begin;
}
int value = begin.data;
ListNode index = begin;
ListNode cur = begin.nextNode;
while(cur!=null){
if(cur.data<value){
index = index.nextNode;
int temp = cur.data;
cur.data = index.data;
index.data = temp;
}
cur = cur.nextNode;
}
begin.data = index.data;
index.data = value;
return index;
}
}
@Test
public void test_QuickSort(){
ListNode listNode = new ListNode(8)
listNode.nextNode = new ListNode(4)
listNode.nextNode.nextNode = new ListNode(2)
listNode.nextNode.nextNode.nextNode = new ListNode(5)
ListNode end = listNode.nextNode.nextNode.nextNode
QuickSort quickSort = new QuickSort()
quickSort.quickSort(listNode,end)
ListNode head = quickSort.quickSort(listNode,end)
while (head!=null){
System.out.print(head.data+"->")
head = head.nextNode
}
}
合并两个有序链表,合并后依然有序
对两个有序链表进行合并
step1:判断两个链表是否为空:如果链表1为空,则直接返回链表2;如果链表2为空,直接返回链表1;
step2:若两个链表都不为空,比较头结点head1和head2的大小,选出较小的作为合并后链表的头结点,
同时将小的head向后移以方便后续的比较
step3:设置一个临时变量,用来后续连接其他节点
step4:再比较head1和head2的大小,找出较小的,作为合并后链表的第二小节点,用temp.next来表示,同样再进行后移。
step5:重复上述操作,直至head1或者head2为null
step6:当head1或head2一个为空时,表明有一个链表已经全部放入新的链表中,直接将不为空的链表拼接在其后。
package com.struct.interview_question.list_interview_question.combinelist;
import com.struct.interview_question.list_interview_question.listsort.ListNode;
/**
*@Description: 合并两个有序链表合并后依然有序
*@Author: dyy
*/
public class CombineTwoList {
public ListNode combineList(ListNode head1,ListNode head2){
if(head1==null){
return head2;
}
if(head2==null){
return head1;
}
if (head1==null&&head2==null){
return null;
}
ListNode head =null;
if(head1.data<=head2.data){
head = head1;
head1 = head1.nextNode;
}else{
head = head2;
head2 = head2.nextNode;
}
ListNode temp = head;
while (head1!=null&&head2!=null){
if(head1.data<=head2.data){
temp.nextNode = head1;
head1 = head1.nextNode;
}else{
temp.nextNode = head2;
head2 = head2.nextNode;
}
temp = temp.nextNode;
}
if(head1 == null){
temp.nextNode = head2;
}
if(head2 == null){
temp.nextNode = head1;
}
return head;
}
}
@Test
public void test_CombineTwoList(){
ListNode head1 = new ListNode(1)
ListNode head2 = new ListNode(2)
head1.nextNode = new ListNode(3)
head1.nextNode.nextNode = new ListNode(5)
head1.nextNode.nextNode.nextNode = new ListNode(7)
head2.nextNode = new ListNode(4)
head2.nextNode.nextNode = new ListNode(6)
head2.nextNode.nextNode.nextNode = new ListNode(8)
CombineTwoList combineTwoList = new CombineTwoList()
ListNode newNode = combineTwoList.combineList(head1,head2)
while (newNode!=null){
System.out.print(newNode.data+"->")
newNode = newNode.nextNode
}
}