示意图:
/*
* 单链表的合并
*/
class Outer5 {
class Entry {
int data;
Entry next;
public Entry() {
data = 0;
next = null;
}
public Entry(int data) {
this.data = data;
next = null;
}
}
private Entry head = new Entry();
/**
*尾插法
* @param val 需要插入的数据
*/
public void insertlast(int val) {
Entry cur = head;
while(cur.next != null) {
cur = cur.next;
}
Entry entry = new Entry(val);
cur.next = entry;
}
/*
* 合并有序链表
* @param L1
* @param L2
* @return 合并好的新链表
*/
public static Outer5 HebinLianbiao(Outer5 L1,Outer5 L2) {
Outer5 L3 = new Outer5();
Entry p1 = L1.head.next;
Entry p2 = L2.head.next;
Entry p = L3.head;
if(L1 == null || L1.head.next == null) {
return L2;
}
if(L2 == null || L2.head.next == null) {
return L1;
}
while(p1 != null && p2!= null) {
if(p1.data < p2.data) {
p.next = p1;
p1 = p1.next;
}
else if(p1.data > p2.data) {
p.next = p2;
p2 = p2.next;
}else {
p.next = p1;
p1 = p1.next;
}
p = p.next;
}
if(p1 == null) {
p.next = p2;
}
else if(p2 == null) {
p.next = p1;
}
return L3;
}
//输出
public void show() {
Entry cur = head;
while(cur.next != null) {
cur = cur.next;
System.out.print(cur.data+" ");
}
System.out.println();
}
}
public class Lianxi1 {
public static void main(String[] args) {
Outer5 s= new Outer5();
System.out.println("链表1");
s.insertlast(25);
s.insertlast(45);
s.insertlast(65);
s.insertlast(85);
s.show();
Outer5 x= new Outer5();
System.out.println("链表2");
x.insertlast(15);
x.insertlast(35);
x.insertlast(55);
x.insertlast(75);
x.insertlast(95);
x.show();
System.out.println("合并后链表");
Outer5 h = Outer5.HebinLianbiao(s,x);
h.show();
}
}
上面的合并方法比较好理解,但写的话最好是调用其他方法算,别写在一个方法里面,以下是合并链表的其他两种方法:
1.递归法:
/**
* 合并两个有序链表
* @param h1
* @param h2
* @return 合成后的链表
*/
public static Outerq RecursiveMergeLink(Outerq h1,Outerq h2)
{
Outerq h3 = new Outerq();
Entry h11 = h1.head.next;
Entry h22 = h2.head.next;
h3.head.next = RecursiveMergeEntry(h11, h22);
return h3;
}
/**
* 连接节点 递归法
* @param h1
* @param h2
* @return 连接好后的第一个节点
*/
public static Entry RecursiveMergeEntry(Entry h1,Entry h2)
{
Entry h3= null; //临时变量保存当前需要被插入的节点
if(h1 == null) //如果h1等于null了则h1已经被连接完成,此处只需要链接剩下的h2即可
return h2;
else if(h2 == null) //如果h2等于null了则h2已经被连接完成,此处只需要链接剩下的h1即可
return h1;
else
{
if(h1.data < h2.data) //如果h1比h2小
{
h3 = h1; //则当前节点为h1
h3.next = RecursiveMergeEntry(h1.next,h2); //进行后续节点的连接
}
else if(h1.data > h2.data)//同上
{
h3 = h2;
h3.next = RecursiveMergeEntry(h1,h2.next);
}
else //当两个相等的时候,同时往后移位
{
h3 = h1; //则当前节点为h1
h3.next = RecursiveMergeEntry(h1.next,h2.next); //进行后续节点的连接
}
return h3; //返回当前节点给上一层递归 当返回的时候 当前节点之后的节点都已经连接完成
}
}
2.非递归法:
/**
* 合并两个有序链表
* @param h1
* @param h2
* @return 合成后的链表
*/
public static Outerq RecursiveMergeLink(Outerq h1,Outerq h2)
{
Outerq h3 = new Outerq();
Entry h11 = h1.head.next;
Entry h22 = h2.head.next;
h3.head.next = RecursiveMergeEntry(h11, h22);
return h3;
}
/**
* 合并两个有序链表非递归
* @param h1
* @param h2
* @return
*/
public static Outerq MergeLink(Outerq h1,Outerq h2) {
Outerq h3 = new Outerq();
if(h1 == null||h1.head.next==null) //若某一个链表为空 直接返回另一个链表
return h2;
if(h2 == null||h2.head.next==null)
return h1;
Entry e1 = h1.head.next; //获得两个链表的第一个数据域
Entry e2 = h2.head.next;
Entry e3 = h3.head; //获取临时链表的头结点
while(e1!=null&&e2!=null) //循环直到某一个链表为空
{
if(e1.data>e2.data) //进行判断
{
e3.next = e2; //连接
e2 = e2.next; //移位
}else if(e1.data<e2.data) //同上
{
e3.next = e1;
e1 = e1.next;
}
else //防止存在两个相等的元素,去除掉一个
{
e3.next = e2;
e2 = e2.next;
continue;
}
e3 = e3.next; //连接后将e3向后移动
}
// if(e1 == null) //当e1为空时,剩下的为h2 需要将h2剩余的节点e2连上
// {
// e3.next = e2;
// }
// else if(e2 == null) //同上
// {
// e3.next = e1;
// }
e3.next = e1==null?e2:e1; //和上面if相同
return h3; //返回临时链表h3
}