了解链表之前先区分两个概念:
1.0 顺序表:用地址连续的存储单元顺序存储线性表中的各个数据元素,逻辑上相邻的数据元素在物理位置上也相邻。(常见的数组)
2.0 链表不要求逻辑上相邻的数据元素在物理位置上也相邻。
链表:
先了解链表:
定义:链表使用一组任意的存储单元来存储线性表中的数据元素。在存储数据元素时,除了要存储数据元素本身的信息外,还要存储与它相邻的数据元素的地址信息,这两部分组成该数据元素,称为节点。
通常:把数据元素本身的信息的域称为数据域
地址信息的域称为引用域。
单链表:如果该节点的引用域只存储该节点直接后继节点的存储地址,该链表叫单链表(Singly Linked List);
头结点:指向链表第一个节点的唯一标识,数据域为空;
头节点的加入完全是为了操作的方便,数据域为空引用域存放的是第一个节点的地址,空表时该引用为空。
链表的优点:非常适合于频繁的进行插入和删除,同时很少进行查询的场合。
(缺点:自然就是查询太慢)
来个小李子看看吧:
题目:有数据类型为整型的单链表Ha和Hb,其数据元素均从小到大的顺序进行排列,编写算法把他们合并为一个单链表Hc,要求Hc中节点中的值也是升序排列的。
解题方法一:
思路:扫描Ha和Hb中的节点比较当前节点的值,小的附加到Hc的末尾,如此直至一个链表被扫描完,然后将剩下的部分附加到Hc的末尾即可哦;
源码如下:
public LinkedList<int> Merge(LinkedList<int> Ha, LinkedList<int> Hb)
{
LinkedList<int> Hc = new LinkedList<int>();
LinkedListNode<int> p = Ha.First;//第一个节点
LinkedListNode<int> q = Hb.First;//第二个节点
LinkedListNode<int> s = new LinkedListNode<int>(0);//自定义的节点,生命时必须提供参数值
while (p!=null&&q!=null)//两个节点都不为空
{
if (p.Value < q.Value)
{
s = p;
p = p.Next;
}
else
{
s = q;
q = q.Next;
}
Hc.AddLast(s.Value);
}
//根据条件(p!=null&&q!=null)如果p为空进行赋值,不为空就进行遍历附加到Hc的尾部
if (p==null)
{
p = q;
}
while (p!=null)
{
s = p;
p = p.Next;
Hc.AddLast(s.Value);
}
return Hc;
}
经过测试上面的代码没有任何的问题;
解题方法二:
因为在单链表的尾部添加内容非常花时间,因为定位最后一个节点需要从开头开始遍历。
但是插入到链表头部要节省很多时间,但是这样获取到的结果是降序的哦;
源代码如下:(这是降序排列)
public LinkedList<int> Merge(LinkedList<int> Ha, LinkedList<int> Hb)
{
LinkedList<int> Hc = new LinkedList<int>();
LinkedListNode<int> p = Ha.First;//第一个节点
LinkedListNode<int> q = Hb.First;//第二个节点
LinkedListNode<int> s = new LinkedListNode<int>(0);//自定义的节点,生命时必须提供参数值
while (p != null && q != null)//两个节点都不为空
{
if (p.Value < q.Value)
{
s = p;
p = p.Next;
}
else
{
s = q;
q = q.Next;
}
Hc.AddFirst(s.Value);
}
//根据条件(p!=null&&q!=null)如果p为空进行赋值,不为空就进行遍历附加到Hc的尾部
if (p == null)
{
p = q;
}
while (p != null)
{
s = p;
p = p.Next;
Hc.AddFirst(s.Value);
}
return Hc;
}