什么是链表
图中每个结点都包括两个内容:
- 数据部分,保存的是该结点的实际数据,
- 地址部分,保存的是下一个结点的地址,
链表结构就是由许多的结点构成的。在进行链表操作时,首先定义一个“头引用“变量,该引用变量指向指向链表结构的第一个结点,第一个结点地址部分又指向第二个结点…直到最后一个结点。一般在表尾的结点地址部分放一个空地址null。
由于采用引用来指示下一个数据地址,因此在链表结构中,逻辑上相邻的结点在内存中不一定相邻,逻辑相邻关系通过地址部分的引用变量实现。
链表的好处
链表结构带来最大的好处就是结点之间不要求连续存放,因此在保存大数据使,不需要分配一块相邻的存储空间,用户可以用过new函数动态分配结点空间,当删除某个结点市,给该结点赋值null,释放其占用的空间。
当然,链表结构也有缺点,就是浪费空间,因此,对每个结点数据,都要额外分配一个应用变量,因此在某些场合,链表结构带来的好处还是大于其缺点的。
链表案例
//定义表数据
public class Data
{
public string key; //终点关键字
public string name;
public string age;
}
//定义表结构
public class CLType
{
Data nodeData = new Data();
CLType nextNode;
//追加结点
public CLType CLAddEnd(CLType head, Data nodeData)
{
CLType node, htermp;
if ((node = new CLType()) == null)
{
Console.WriteLine("申请内存失败");
return null;
}
else
{
node.nodeData = nodeData; //保存数据
node.nextNode = null; //设置表尾
htermp = head; //头引用
while (htermp.nextNode != null) //检查链表的末尾
{
htermp = head.nextNode;
}
htermp.nextNode = node;
return head;
}
}
public CLType CLAddFirst(CLType head, Data nodeData)
{
CLType node;
if ((node = new CLType()) == null)
{
Console.WriteLine("申请内存失败");
return null;
}
else
{
node.nodeData = nodeData; //保存数据
node.nextNode = head; //设置表尾
head = node;
return head;
}
}
//查找结点
public CLType CLFindNode(CLType head, string key)
{
CLType htremp;
htremp = head; //保存链表头引用
while (htremp != null)
{
if (htremp.nodeData.key.CompareTo(key) == 0) //若结点关键字与传入的关键相同
{
return htremp; //返回该结点的引用
}
htremp = htremp.nextNode; //处理下一个结点;
}
return null;
}
//插入结点
public CLType CLInsertNode(CLType head, string key, Data nodeData)
{
CLType node, nodeTemp;
if ((node = new CLType()) == null)
{
Console.WriteLine("申请内存失败");
return null;
}
node.nodeData = nodeData; //保存结点中的数据
nodeTemp = CLFindNode(head, key);
if (nodeTemp != null) //若找到要插入的结点
{
node.nextNode = nodeTemp.nextNode; //新插入的结点指向关键结点的下一个结点
nodeTemp.nextNode = node; //设置关键结点指向新的插入结点
}
else
{
Console.WriteLine("没有找到正确的插入位置");
node = null;
}
return head; //返回头结点引用
}
public int DeleteNode(CLType head, string key)
{
CLType node,htemp; //node保存删除结点的前一结点
htemp = head;
node = head;
while (htemp != null)
{
if (htemp.nodeData.key.CompareTo(key) == 0) //找到关键字执行删除操作;
{
node.nextNode = htemp.nextNode; //使当前结点指向当前结点的下一个结点
htemp = null;
return 1;
}
else
{
node = htemp;
htemp = htemp.nextNode;
}
}
return 0;
}
//计算表长
public int CLLength(CLType head)
{
CLType htemp;
int len = 0;
htemp = head;
while (htemp != null)
{
len++;
htemp = htemp.nextNode;
}
return len;
}
//遍历链表
public void CLAllNode(CLType head)
{
CLType htrmp;
Data nodeData;
htrmp = head;
while (htrmp != null) //循环遍历
{
nodeData = htrmp.nodeData;
//打印数据
htrmp = htrmp.nextNode; //处理下一个结点
}
}
}