由于链表合并时需要使用类定义中的Head,Node,Node.Data,Node.Next等,必须将MergeList作为LinkList类的方法,才能满足上述需求。在具体实现时可采用两种方式:
一种是严老师课本上算法2.12的方式,这种方式无需新建链表,直接为原先连个链表建立新的连接关系,生成新的链表。
第二种需要建立全新的链表,并不破坏原来的La和Lb。
先看第一种方式,我把类结构也简单罗列了一下。
Class LinkList
{
public int Length;
private Node Head;
public LinkList(){}
{
//……
}
public object GetElem(int i)
{
//……
}
public void Print()
{
//……
}
public bool Insert(int i,object e)
{
//……
}
//以下为合并链表的方法
public void MergeList(LinkList la, LinkList lb)
{
Node pa = la.Head.Next; //定义La的辅助指针
Node pb = lb.Head.Next; //定义Lb的辅助指针
Node pc = la.Head; //定义Lc的辅助指针,注意Lc要在La,Lb之前
Head = la.Head; //Head即为Lc.Head,指向La.Head
while (pa != null && pb != null) //若La和Lb中的元素都没有取完
{
if (int.Parse(pa.Data.ToString()) < int.Parse(pb.Data.ToString())) //La当前元素与Lb当前元素比较
{
pc.Next = pa; //若La当前元素小,则将pc链接域指向La当前元素结点
pc = pa; //pc后移一位,准备迎接新的元素结点
pa = pa.Next; //pa后移一位,准备下一次比较
}
else
{
pc.Next = pb; //若Lb当前元素小,则将pc链接域指向Lb当前元素结点
pc = pb; //pc后移一位,准备迎接新的元素结点
pb = pb.Next; //pb后移一位,准备下一次比较
}
}
//La和Lb当中有一个链表元素被取完,就结束循环到下面的语句
if (pa != null) //如果La有剩余,则将La余下部分链表一次性连接到pc上
pc.Next=pa;
else if(pb!=null) //如果Lb有剩余,则将Lb一下部分链表一次性连接到pc上
pc.Next=pb;
}
private class Node
{
//……
}
}
下面是第二种方式:
public void MergeList2(LinkList la, LinkList lb)
{
Node pa = la.Head.Next; //定义La的辅助指针pa,并定位到首元结点
Node pb = lb.Head.Next; //定义Lb的辅助指针pb,并定位到首元结点
Node pc = Head; //定义Lc(this)的辅助指针pc,并定位到头结点,作用同课本中的p
Node sc; //定义插入结点辅助指针sc,作用同于课本中的s
while (pa != null && pb != null) //当La与Lb中的元素都没有取完时进行循环
{
if (int.Parse(pa.Data.ToString()) < int.Parse(pb.Data.ToString())) //如果La的当前元素小于Lb的当前元素
{
sc = new Node(pa.Data); //若上述条件为真,克隆La的当前结点为sc
pa = pa.Next; //pa后移一位,准备下一次比较
}
else
{
sc = new Node(pb.Data); //若上述条件为假,克隆Lb的当前结点为sc
pb = pb.Next; //pa后移一位,准备下一次比较
}
sc.Next = pc.Next; //结点sc插入pc之后
pc.Next = sc; //结点sc插入pc之后
pc = sc; //pc后移一位到当前结点
Length++; //当前链表(Lc)长度加一
}
while(pa != null) //若La还有剩余元素,则依次插入当前链表中
{
sc = new Node(pa.Data); //克隆La的当前结点为sc
sc.Next = pc.Next; //结点sc插入pc之后
pc.Next = sc; //结点sc插入pc之后
pc = sc; //pc后移一位到当前结点
Length++; //当前链表(Lc)长度加一
pa = pa.Next; //pa后移一位,准备插入下一个结点
}
while (pb != null)
{
sc = new Node(pb.Data); //克隆La的当前结点为sc
sc.Next = pc.Next; //结点sc插入pc之后
pc.Next = sc; //结点sc插入pc之后
pc = sc; //pc后移一位到当前结点
Length++; //当前链表(Lc)长度加一
pb = pb.Next; //pb后移一位,准备插入下一个结点
}
}