【Weiss】【第03章】练习3.3:通过交换指针交换单/双链表元素
2015-03-11 06:05
127 查看
【练习3.3】
通过之调整指针(而不是数据)来交换两个相邻的元素,使用
a.单链表
b.双链表
Answer:
先放测试代码,折叠标题可以看到分别是哪种链表的测试。
实测可满足题意,但单链表和双链表的两段代码是分开实现的,所以需要分开测试。
如果要合在一起的话,需要改一下头文件包含以及命名空间。
单链表测试代码:
View Code
通过交换指针交换节点直观上还是比较容易的,但是需要比较细致否则容易做错。
因为注释不太好解释,所以代码上就不放注释了,直接上图比较直观。
首先以单链表为例,pos是头节点的情形可以当做一种特殊情况,处理方法比一般情况要简单。
更一般地,通过迭代找到pos的前驱,在后面的实现代码里记为iter变量,然后几个指针的变化关系如下图。
最后的问号代表该处可能是一个节点,也可能是nullptr,但是对于单链表而言没有影响。
考虑双链表时,同样不考虑pos是头指针的情况(当然在代码里还是要表现的),有三点细微的不一致
①、不需从链表头迭代寻找pos的前驱iter,在没有修改前向指针的情况下,可以把单链表书写中的iter全部写成pos->prev
②、按单链表的方法,修改完后向指针后,需要调整前向指针
③、尾部的问号节点如果为空,则会对rear的位置产生影响;如果不为空,则需调整该问号节点的前向指针
简图如下:
最后是实现代码,将其分别复制进此前对应的例程中,函数的声明请自行补充。
单链表实现代码:
双链表实现代码:
通过之调整指针(而不是数据)来交换两个相邻的元素,使用
a.单链表
b.双链表
Answer:
先放测试代码,折叠标题可以看到分别是哪种链表的测试。
实测可满足题意,但单链表和双链表的两段代码是分开实现的,所以需要分开测试。
如果要合在一起的话,需要改一下头文件包含以及命名空间。
单链表测试代码:
#include <iostream> #include "double_linklist.cpp" using namespace std; using namespace doublelinklist; template class DList<int>; int main(void) { DList<int> number; //测试插入 cout << "/*additem()*/" << endl; number.additem(2); number.additem(3); number.additem(5); number.additem(7); number.additem(11); number.additem(13); number.additem(17); number.traverse(); cout << "\n/*end*/\n\n" << flush; //测试交换函数 cout << "/*swappos*/" << endl; //测试头节点 number.swappos(number.find(2)); number.traverse(); cout << endl; //测试邻接尾节点的中间节点 number.swappos(number.find(13)); number.traverse(); cout << endl; //测试中间节点 number.swappos(number.find(7)); number.traverse(); cout << endl; //测试尾节点 number.swappos(number.find(13)); cout << "/*end*/\n\n" << flush; system("pause"); }
View Code
通过交换指针交换节点直观上还是比较容易的,但是需要比较细致否则容易做错。
因为注释不太好解释,所以代码上就不放注释了,直接上图比较直观。
首先以单链表为例,pos是头节点的情形可以当做一种特殊情况,处理方法比一般情况要简单。
更一般地,通过迭代找到pos的前驱,在后面的实现代码里记为iter变量,然后几个指针的变化关系如下图。
最后的问号代表该处可能是一个节点,也可能是nullptr,但是对于单链表而言没有影响。
考虑双链表时,同样不考虑pos是头指针的情况(当然在代码里还是要表现的),有三点细微的不一致
①、不需从链表头迭代寻找pos的前驱iter,在没有修改前向指针的情况下,可以把单链表书写中的iter全部写成pos->prev
②、按单链表的方法,修改完后向指针后,需要调整前向指针
③、尾部的问号节点如果为空,则会对rear的位置产生影响;如果不为空,则需调整该问号节点的前向指针
简图如下:
最后是实现代码,将其分别复制进此前对应的例程中,函数的声明请自行补充。
单链表实现代码:
//练习3.3新增,交换相邻节点 template <typename T> bool List<T>::swappos(Node<T>* pos) { if (pos->next == nullptr) { cout << ("Illegal!") << endl; return false; } if (pos == front) { front = front->next; pos->next = front->next; front->next = pos; } else { Node<T>* iter = front; while (iter->next != pos) iter = iter->next; if (iter == nullptr) { cout << ("Illegal!") << endl; return false; } else { iter->next = pos->next; pos->next = pos->next->next; iter->next->next = pos; } } return true; }
双链表实现代码:
//练习3.3新增,通过交换指针交换节点 //不检测pos位置是否确实在双链表中(否则速度比单链表更慢,失去意义) template <typename T> bool DList<T>::swappos(Node<T>* pos) { if (pos->next == nullptr) { cout << "Illegal" << endl; return false; } if (pos == front) { front = front->next; front->prev = nullptr; pos->next = front->next; pos->prev = front; front->next = pos; } else { //后向指针调整 pos->prev->next = pos->next; pos->next = pos->next->next; pos->prev->next->next = pos; //前向指针调整 pos->prev->next->prev = pos->prev; pos->prev = pos->prev->next; } //判断尾指针是否为空 if (pos->next == nullptr) rear = pos; else pos->next->prev = pos; return true; }
相关文章推荐
- 练习 3.3 通过只调整指针(不是数据)来交换两个相邻的元素
- p62 练习3.3 通过只调整指针(而不是数据)来交换两个相邻的元素,使用:
- 【Weiss】【第03章】练习3.11:比较单链表递归与非递归查找元素
- 单双链表,通过指针变动交换相邻元素
- 【Weiss】【第03章】练习3.16:删除相同元素
- 通过只调整指针(而不是数据)来交换两个相邻的元素
- 练习2: 通过交换函数的实现,学习指针的用法。
- 习题3.3---只通过调整指针来达到相邻结点交换的过程
- C++ 单链表基本操作分析与实现 链表 链表是一种物理存储单元上非连续、非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的。链表由一系列结点(链表中每一个元素称为结点)组成,结
- 【LeetCode23-29+518】 K个有序子链,交换链表顺序(指针调换),Vector删除元素,移位运算符>>,DP算法
- 采用选择排序法对链表进行排序,注意交换操作中不是对链表里某一节点里的某一元素进行交换,而是对两节点指针的交换
- 数据结构与算法分析 c++11 练习3.2 通过只调整链(而不是数据)来交换两个相邻的元素
- 小练习 - 单链表冒泡排序,交换指针域
- Python 实现通过指针实现链表翻转,链表奇偶下标交换,链表的冒泡排序
- 练习3: 通过打印指针,加深对交换函数和指针的理解。
- 【Weiss】【第03章】练习3.15:自调整链表
- 只调整指针来交换两个相邻的元素【双链表】
- 【Weiss】【第03章】练习3.4、3.5:有序链表求交、并
- 有两个数组a,b,大小都为n,数组元素的值任意,无序;要求:通过交换a,b中的元素,使数组a元素的和与数组b元素的和之间的差最小
- C通过函数交换指针的值