数据结构(五)——线性表的链式描述小结

链式描述的线性表(使用指针)对比公式化线性表的优势

  1. 平衡二叉树结构,比如AVL和红黑树,使用基于指针的描述在最坏情况下的插入和删除要优于数组描述。
  2. 链式描述的合并时间复杂度为O(1),在知道前驱的情况下,插入和删除操作的时间复杂度为O(1)
  3. 插入、删除操作用比较操作代替公式化线性表平均移动半个表的操作
  4. 有广泛的应用实例,指针更灵活,不受空间连续性的限制。
  5. 很多很多…

链式描述的线性表的插入、删除操作中内含的思想:

  1. 对链表的操作往往涉及两个指针,一个指针指向首节点以防首地址丢失,另一指针在链表的节点实现删除、插入、合并等操作。比如为了保存firstNode(即链表的首地址),需要新建节点指针类型,即新建一个指针,复制firstNode的地址,来遍历链表。多出的一个指针,为链表提供了更灵活的操作,比如实现链表的延长、chain成员函数的箱子排序
  2. 利用C++的赋值运算符“=”,将右边操作数的值传给左边操作数并保存,且都为地址操作。
  3. 节点保存有数据,我们操作的是指向节点的指针,通过指针来修改节点的data和指向的地址,多个指针可指向同一节点。

总结一下指针在链表上的基本操作:

1. 延长链表

/*
firstNode: 首节点的指针
addedNode: 增加的节点的指针
toolNode: 在链表上进行操作的节点指针,作用是实现在链表上添加节点
*/
// 将addedNode1,加到firstNode的后面
toolNode = firstNode;// ①
toolNode->next = addedNode1;// ② 添加节点完成
toolNode = toolNode->next;// ③,这一步也可写成toolNode = addedNode1; 工具指针向前移动一个节点,为下次添加节点做准备
//将addedNode2加到addedNode1后面,组成三个节点的链表
toolNode->next = addedNode2;// ④
toolNode = toolNode->next;// ⑤

2. 删除链表中的节点

/*
有三个节点,node1,node2,node3依次链接
假设我们要删除node2,首先我们要定位到node1,使用for循环或迭代器
然后,
*/
deletedNode = node1->next; // 此时要删除的节点的地址成功被保存
node1->next = node1->next->next; // 此时链表上node1->next和node2都指向node3,即使node3为空也没关系,都指向空
delete deletedNode; 删除node2,此时只有node1->next指向node3,node2占用的空间和地址都莫得了

3. 两个链表的连接
在箱子排序中,把箱子中的节点收集到有序节点这一步,详细代码在《数据结构 C++描述》第二版P133,涉及四类指针的操作,这里只分析合并操作(只是有点懒不想全码下来嘿嘿,其实整个代码都很优美,整体看下来是最好的)

/*
firstNode 指向首节点,作用是保存连接后的链表的首地址
toolNode 在链表上进行操作的节点指针,在这里用于连接两个链表的头和尾,和延长链表时的作用很相似
bottomNode 指向某一箱子链表的底部的指针
topNode 指向某一箱子链表的顶部的指针(与bottomNode为同一箱子链表)
*/
if(toolNode == null)
	firstNode = bottomNode;// 说明这是第一个箱子,第一个箱子的底部节点当然要保存到firstNode上
else
	toolNode ->next = bottomNode;// 此时链表最顶部的节点的next已经连接到下一个箱子链表的底部节点,连接完成
toolNode = topNode;// 指针移动到下一箱子链表的顶部节点,为下一次合并准备

猜你喜欢

转载自blog.csdn.net/qq_41882686/article/details/106725457
今日推荐