姓名:Far_Rainbow
学号: 202505000X
专业: 软件工程
年级:2020级
实验名称:实验3 单链表的基本操作实现
实验内容:
(1)实验目的
通过该实验,深入理解链表的逻辑结构、物理结构等概念,掌握链表基本操作的编程实现,熟练掌握C语言中指针的操作。和实验2对比,掌握线性结构两种不同存储方式的区别。
(2)实验内容
编程实现链表下教材第二章定义的线性表的基本操作,最好用菜单形式对应各个操作,使其编程一个完整的小软件。注意,每个功能模块一定要考虑非法的情况,并作出相应的提示,例如:求前驱,要分别能够测试第一个元素的前驱、其他正常的元素的前驱、输入一个在表中不存在的元素求其前驱,这三种情况应给出相应的提示语和结果值;插入和删除时要考虑插入或删除的位置是否合法等。
(3)实验要求:
菜单项包括:
- 初始化或重置链表
- 销毁链表
- 清空链表
- 链表长度
- 指定位置的元素值
- 链表已存在元素的位序
- 求输入元素的直接前驱
- 求输入元素的直接后继
- 在第i个位置插入一个元素
- 删除第i个元素
- 输出有的链表元素
- 初始化并用头插法(或尾插法)输入元素
- 实现单链表的逆序存放
要求:所有的提示语和输出语句不允许出现在自定义的函数中,只能在main函数中出现提示语。
注:销毁链表时需要循环释放每个结点所占用的空间。
注:求前驱是指,输入一个元素值(而不是位置),求该元素在顺序表中的直接前驱元素值。求后继是指:输入一个元素值(而不是位置),求该元素在顺序表中的直接后继元素值。
(4)验收/测试用例
参考实验2
实验类型:验证性
实验的重难点:链表的定义和实现
实验环境:TDM-GCC 4.9.2 64-bit
实验步骤及完成任务情况:
一、设计思想
- 采用模板实现泛型编程,可创建任意数据类型的单链表;
- 采用链式存储方式,插入删除时间复杂度都是
#card=math&code=O%281%29&id=uXxHU)
二、主要源代码
#include <iostream>using std::cin;using std::cout;using std::endl;template <typename T> struct Lnode {T data;Lnode<T>* next;};template <typename T> class List {private:int _length;Lnode<T>* header;public:void init() {header = new Lnode<T>; header->next = NULL; _length = 0;}void destroy();void clear();List() {header = NULL; }~List() {destroy(); }bool exist() const {return header != NULL ? 1 : 0;}bool isempty() const {return _length > 0 ? 0 : 1; }int getlength() const {return _length; }Lnode<T>* find(int pos);int elemlocate(T const& e);Lnode<T>* priornode(T const& e);Lnode<T>* nextnode(T const& e);Lnode<T>* insert(int pos, T const& e);T remove(int pos);void traverse();void create(int n);Lnode<T>* reverse();};template <typename T> void List<T>::destroy(){if (!exist()) return;Lnode<T>* p = header, *q;while(p){q = p->next;delete p;p = q;}header = NULL;_length = 0;}template <typename T> void List<T>::clear(){Lnode<T>* p = header->next, *q;while(p){q = p->next;delete p;p = q;}_length = 0;}template <typename T> Lnode<T>* List<T>::find(int pos){int count = 0;Lnode<T>* p = header->next;while(p){count ++;if(count == pos) return p;p = p->next;}return NULL;}template <typename T> int List<T>::elemlocate(T const& e){int count = 0;Lnode<T>* p = header->next;while(p){count ++;if(p->data == e) return count;p = p->next;}return 0;}template <typename T> Lnode<T>* List<T>::priornode(T const& e) //////{Lnode<T>* p = header->next, *q;while(p){q = p->next;if(q && q->data == e) return p;p = q;}return NULL;}template <typename T> Lnode<T>* List<T>::nextnode(T const& e) //////{Lnode<T>* p =header->next, *q;while(p){q = p->next;if(q && p->data == e) return q;p = q;}return NULL;}template <typename T> Lnode<T>* List<T>::insert(int pos, T const& e){int count = 0;Lnode<T>* p = header; //注意考虑插入到首元结点的位置,故不用p=header->next;Lnode<T>* q = new Lnode<T>;q->data = e;while(p){count ++;if(count == pos){q->next = p->next;p->next = q;++ _length;return q;}p = p->next;}return NULL;}template <typename T> T List<T>::remove(int pos) // 删不了第一个元素 和非法情况{int count = 0;Lnode<T>* p = header->next, *q;while(p){q = p->next;count ++;if(count == pos-1){p->next = q->next;T e = q->data;delete q;-- _length;return e ;}p = q;}}template <typename T> void List<T>::traverse(){Lnode<T>* p = header->next;while(p){cout<<p->data<<' ';p = p->next;}}template <typename T> void List<T>::create(int n){Lnode<T>* p;while(n --){p = new Lnode<T>;cout<<"请输入想要插入的值:";cin>>p->data;p->next = header->next;header->next = p;++ _length;}}template <typename T> Lnode<T>* List<T>::reverse(){if(header == NULL || header->next == NULL) return header;Lnode<T>* now = header->next, *pre = NULL, *next = NULL;while(now){next = now->next;now->next = pre;pre = now;now = next;}header->next = pre;return header;}int main(){cout<<"\n 基单链表的基本操作实现\n\n";cout<<"1---初始化一个单链表\n";cout<<"2---销毁单链表\n";cout<<"3---清空单链表\n";cout<<"4---求单链表长度\n";cout<<"5---获取线性表中指定位置的元素\n";cout<<"6---获取单链表元素的位置\n";cout<<"7---求前驱\n";cout<<"8---求后继\n";cout<<"9---在单链表指定位置插入元素\n";cout<<"10--删除单链表指定位置的元素\n";cout<<"11--显示单链表\n";cout<<"12--初始化并用头插法输入元素\n";cout<<"13--实现单链表的逆序存放\n";cout<<"\n\t退出,输入一个负数!\n\n";List<int> L;while(true){int myOption;cout<<"\n请输入操作序号:";cin>>myOption;switch(myOption){case 1:{if(L.exist()){cout<<"初始化失败,单链表已存在!\n";break;}L.init();cout<<"初始化成功!\n";break;}case 2:{if (!L.exist()){cout<<"销毁失败,单链表不存在\n";break;}L.destroy();cout<<"销毁成功!\n";break;}case 3:{if (!L.exist()){cout<<"清空失败,单链表不存在\n";break;}if (L.isempty()) ;else L.clear();cout<<"清空成功!\n";break;}case 4:{if (!L.exist()){cout<<"请先创建单链表!\n";break;}cout<<"单链表的长度是"<<L.getlength()<<endl;break;}case 5:{if (!L.exist()){cout<<"单链表不存在,请先创建单链表!\n";break;}if (L.isempty()){cout<<"单链表为空,请先插入元素!\n";break;}cout<<"请输入你要获取元素的位置:";int pos;cin>>pos;Lnode<int>* ptr = L.find(pos);if (!ptr) {cout<<"不存在该位置的元素\n";break;}cout<<"第"<<pos<<"位元素是 "<<ptr->data<<endl;break;}case 6:{if (!L.exist()){cout<<"单链表不存在,请先创建单链表!\n";break;}if (L.isempty()){cout<<"单链表为空,请先插入元素!\n";break;}cout<<"请输入您要获取位置的元素:";int e;cin>>e;if (!L.elemlocate(e)){cout<<"单链表中不存在该元素!\n";break;}cout<<"元素"<<e<<"的位置是"<<L.elemlocate(e)<<endl;break;}case 7:{if (!L.exist()){cout<<"单链表不存在,请先创建单链表!\n";break;}if (L.isempty()){cout<<"单链表为空,请先插入元素!\n";break;}cout<<"请输入您要获取前驱的元素:";int pos, e;cin>>e;Lnode<int>* ptr = L.priornode(e);if (!ptr){cout<<"获取失败,该元素不存在或无前驱!\n";break;}cout<<"元素"<<e<<"的前驱元素是"<<(ptr-1)->data<<endl;break;}case 8:{if (!L.exist()){cout<<"单链表不存在,请先创建单链表!\n";break;}if (L.isempty()){cout<<"单链表为空,请先插入元素!\n";break;}cout<<"请输入您要获取后继的元素:";int e;cin>>e;Lnode<int>* ptr = L.nextnode(e);if (!ptr){cout<<"获取失败,该元素不存在或无后继!\n";break;}cout<<"元素"<<e<<"的后继元素是"<<(ptr+1)->data<<endl;break;}case 9:{if (!L.exist()){cout<<"单链表不存在,请先创建单链表!\n";break;}cout<<"请输入指定位置:";int pos;cin>>pos;cout<<"请输入想要插入的值:";int e;cin>>e;if (!L.insert(pos, e)){cout<<"插入失败,请重新尝试!\n";break;}else cout<<"插入完毕!\n";break;}case 10:{if (!L.exist()){cout<<"单链表不存在,请先创建单链表!\n";break;}if (L.isempty()){cout<<"单链表为空!\n";break;}cout<<"请输入你要删除的元素的位置:";int pos;cin>>pos;int e = L.remove(pos);if (!e){cout<<"删除失败,请重新尝试!\n";break;}else cout<<"删除完毕!"<<"被删除的元素是"<<e<<endl;;break;}case 11:{if (!L.exist()){cout<<"单链表不存在,请先创建单链表!\n";break;}if (L.isempty()){cout<<"单链表为空!\n";break;}cout<<"单链表的所有元素是:";L.traverse();cout<<endl;break;}case 12:{if (!L.exist()){cout<<"单链表不存在,请先创建单链表!\n";break;}cout<<"请输入你想插入的元素个数:";int n;cin>>n;L.create(n);break;}case 13:{if (!L.exist()){cout<<"单链表不存在,请先创建单链表!\n";break;}if (L.isempty()){cout<<"单链表为空!\n";break;}cout<<"逆置前的单链表为:";L.traverse();cout<<endl<<"逆置后的单链表为:";L.reverse();L.traverse();cout<<endl;break;}}if(myOption >13 || myOption == 0) cout<<"\n请输入小于13的正整数\n\n";if(myOption < 0){cout<<"\n退出程序!\n";break;}}return 0;}
