链表的实现

来源:互联网 发布:网络大v怎么赚钱 编辑:程序博客网 时间:2024/05/17 23:39

链表的实现

具体代码请点击此处请访问github上的LinkList.h文件

为什么我们需要链表?

在这之前我们已将创建了线性表,这足以来完成我们的一些简答任务了,但是线性表存在以下几个不足之处:

  1. 当我们进行插入或者删除操作的时候,会造成一个线性表内部内存中的内容大量的移动,造成一定的开销;
  2. 上面提到的内存中内容移动其实是进行复制操作,当我们线性表中使用的元素是基本的数据类型时,开销还不算特别大,但是当线性表中的元素为自定义的类型时,进行复制操作时可能需要较大的花销;

当我们使用链表这种数据结构的时候,就能够很好的解决这两个问题了。

链表的表达形式

image

这张图很好的展示出了一个链表的表达形式。图中共色方块,箭头,蓝色圆形组成的一个链式结构可以看做是一个链表。蓝色的圆形是链表的组成单元–节点。

一个节点由两部分构成:
1. _value: 用来存放我们需要放进容器(链表)中的元素;
2. _next: 用来指向下一个节点。

从图中可以看出,_header这个节点的颜色和形状和其他的节点不一样,因为_header节点只是为了链表的操作方便,并不用来存放数据。

链表的增删改查

和线性表一样,我们首先需要实现链表的插入,删除,更改,查询的功能。其中的重要部分为插入和删除的部分。

插入

image

这张图片很形象的描述出了插入新节点的方法。我们假设newNode这个节点要插入到Node2这个节点所在的位置,那么我们首先要断开Node2前面的节点和Node2节点的连接,然后再将Node1和newNode相连,newNode与Node2相连。这样我们的插入工作就完成了。(实际实现的代码中,上述的顺序会有略微的改变)

下面用部分代码切实上诉文字:

Node* getCurrentNodePre(int pos);   //获取pos位置处节点的前一个节点bool insert(int pos, T obj) {    //...一系列参数判断的操作...    Node* newNode = new Node();    if (newNode) {        newNode->_value = obj;        Node* currentPre = getCurrentNodePre(pos);        newNode->_next = currentPre->_next;        currentPre->_next = newNode;    //...一系列其他操作...        }}
删除

image

同样,通过这张图片,也能够很好的理解删除的操作。假设我们要将Node2这个节点删除,那么我们首先要断开Node1与Node2之间的连接,并且将Node1指向Node3。虽然这里我们没有断开Node2和Node3之间的连接,但是我们已将Node2删除了,所以也就相当于间接的将这个连接断开了。(实际实现的代码中,上述的顺序会有略微的改变)。

下面用部分代码切实上诉文字:

Node* getCurrentNodePre(int pos);   //获取pos位置处节点的前一个节点bool remove(int pos) {    //...一系列参数判断的操作...    Node* currentPre = getCurrentNodePre();    Node* toDel = currentPre._next;    currentPre._next = toDel->_next;    delete toDel;//...一系列其他操作...    }