数据结构实验报告
实验名称: 实验1——单链表的构造 学生姓名: XXXXNB 班 级: XXXX 班内序号: 学 号:XXXX 日 期: XXXXX
1.实验要求
根据线性表的抽象数据类型的定义,完成带头结点的单链表的基本功能。 单链表的基本功能:
1、构造:使用头插法、尾插法两种方法
2、插入:要求建立的链表按照关键字从小到大有序 3、删除 4、查找 5、获取链表长度 6、销毁
7、其他:可自行定义
编写测试main()函数测试线性表的正确性。
2. 程序分
编程完成单链表的一般性功能如单链表的构造:使用头插法、尾插法两种方法插入:
要求建立的链表按照关键字从小到大有序,删除,查找,获取链表长度,销毁
用《数据结构》中的相关思想结合C++语言基本知识编写一个单链表结构。本程序为使用方便,几乎不用特殊的命令,只需按提示输入即可,适合更多的用户使用。
2.1 存储结构
单链表的存储结构:
第1页
北京邮电大学信息与通信工程学院
2.2 关键算法分析
1.头插法
自然语言描述:a.在堆中建立新结点
b.将a[i]写入到新结点的数据域 c.修改新结点的指针域
d.修改头结点的指针域,将新结点加入链表中 //在构建之初为了链表的美观性构造,进行了排序 代码描述:
//头插法构造函数 template LinkList for (int i = n - 1; i >= 1; i--)//冒泡排序,对数组进行从小到大排序 { for (int j = 0; j < i; j++) { } 第2页 if (a[j]>a[j + 1]) { } T t = a[j + 1]; a[j + 1] = a[j]; a[j] = t; 北京邮电大学信息与通信工程学院 } } front = new Node < T >;//为头指针申请堆空间 front->next = NULL;//构造空单链表 for (int i = n - 1; i >= 0; i--) { } Node front->next = s;//修改头结点的指针域,将新结点加入到链表中 2.尾插法 自然语言描述:a.在堆中建立新结点 b.将a[i]写入到新结点的数据域 c.将新结点加入到链表中 d.修改修改尾指针 代码描述: //尾插法构造函数 template LinkList front = new Node < T > ; Node Node 第3页 北京邮电大学信息与通信工程学院 s->data = a[i]; r->next = s; r = s; } r->next = NULL; } 时间复杂度:O(n) 3.析构函数 自然语言描述:a.新建立一个指针,指向头结点 b.移动a中建立的指针 c.逐个释放指针 代码描述: template LinkList Node 第4页 front = p; p = p->next; delete front; 北京邮电大学信息与通信工程学院 } 4.按位查找函数 自然语言描述: a.初始化工作指针p和计数器j,p指向第一个结点,j=1 b.循环以下操作,直到p为空或者j等于1 b1:p指向下一个结点 b2:j加1 c.若p为空,说明第i个元素不存在,抛出异常 d.否则,说明p指向的元素就是所查找的元素,返回元素地址 代码描述: template Node Node if(jp = p->next; j++; } if(!p) throw\"查找位置非法\"; else return p; } 时间复杂度:O(n) 第5页 北京邮电大学信息与通信工程学院 5.按值查找函数 自然语言描述:a.初始化工作指针p和计数器j,p指向第一个结点,j=1 b.循环以下操作,找到这个元素或者p指向最后一个结点 b1.判断p指向的结点是不是要查找的值,如果是,返回j; b2.否则p指向下一个结点,并且j的值加一 c.如果找到最后一个结点还没有找到要查找的元素,返回查找失败信息 代码描述: template int LinkList Node if(p->data == x) return j; else { p = p->next; j++; } } 时间复杂度:O(n) 6.插入函数 自然语言描述: a.在堆中建立新结点 第6页 北京邮电大学信息与通信工程学院 b.将要插入的结点的数据写入到新结点的数据域 c.修改新结点的指针域 d.修改前一个指针的指针域,使其指向新插入的结点的位置 代码描述: template void LinkList Node else throw\"插入位置非法\"; Node } 时间复杂度:O(n) 7.按位删除函数 自然语言描述:a.从第一个结点开始,查找要删除的位数i前一个位置i-1的结点 b.设q指向第i个元素 c.将q元素从链表中删除 d.保存q元素的数据 e.释放q元素 代码描述: template T LinkList Node 第7页 北京邮电大学信息与通信工程学院 T x=q->data; } p->next = q->next; delete q; return x; 8.遍历打印函数 自然语言描述: a.判断该链表是否为空链表,如果是,报错 b.如果不是空链表,新建立一个temp指针 c.将temp指针指向头结点 d.打印temp指针的data域 e.逐个往后移动temp指针,直到temp指针的指向的指针的next域为空 代码描述: template void LinkList 第8页 Node cout< 北京邮电大学信息与通信工程学院 9.获取链表长度函数 自然语言描述: a.判断该链表是否为空链表,如果是,输出长度0 b.如果不是空链表,新建立一个temp指针,初始化整形数n为0 c.将temp指针指向头结点 d.判断temp指针指向的结点的next域是否为空,如果不是,n加一,否则return n e.使temp指针逐个后移,重复d操作,直到temp指针指向的结点的next域为0,返回n 代码描述: template int LinkList Node p = p->next; i++; 2.3 其他 异常处理 采用try catch 函数处理异常 如在插入时的异常处理: template void LinkList Node if (i != 1) p = Get(i - 1); try 第9页 北京邮电大学信息与通信工程学院 } { } catch (int i) { } cout << \"插入到位置 \" << i << \" 处\" << \"为错误位置\"< Node 3. 程序运行结果 主函数流程图: 建立 插入 否 测试截图: 初始化链表,菜单创建 开始 创建单链表菜单 初始化 查找 删除 获取长度 退出 是否退出 是 结束 第10页 北京邮电大学信息与通信工程学院 执行功能: 第11页 北京邮电大学信息与通信工程学院 4. 总结 .调试时出现了一些问题如:异常抛出的处理,书中并未很好的提及异常处理,通过查阅资料,选择用try catch 函数对解决。 2.心得体会 了解了单链表的基本的操作函数实现,对链式存储结构有了较好的认识 3.下一步的改进 可以增加完善报错机制,增强程序的健壮性 完整源代码: //单链表的构造 #include template LinkList(){ front = new Node struct Node 第12页 北京邮电大学信息与通信工程学院 }; LinkList(T a[], int n);//有参构造函数,使用含有n个元素的数组a初始化单链表 ~LinkList(); //析构函数,(其在void main 函数最后一句语句之后自动执行,旨在//按次序遍历线性表中的各个数据元素 //获取线性表的长度 //获取线性表第i个位置上的元素结点地址 //查找线性表中值为x的元素,找到后返回其位置 释放栈空间) void PrintList(); int GetLength(); int Locate(T x); Node void Insert(int i, T x);//后插,在线性表的第i个位置上插入值为x的新元素 void insert(int i, T x);//前插,在线性表的第i个位置上插入值为x的新元素 T Delete(int i); Node //删除线性表第i个元素,并将该元素返回 //头指针 private: //头插法构造函数 template LinkList //尾插法构造函数 //template //LinkList // front = new Node < T > ; for (int i = n - 1; i >= 1; i--)//冒泡排序,对数组进行从小到大排序 { } front = new Node < T >;//为头指针申请堆空间 front->next = NULL;//构造空单链表 for (int i = n - 1; i >= 0; i--) { } Node front->next = s;//修改头结点的指针域,将新结点加入到链表中 for (int j = 0; j < i; j++) { } if (a[j]>a[j + 1]) { } T t = a[j + 1]; a[j + 1] = a[j]; a[j] = t; 第13页 北京邮电大学信息与通信工程学院 // Node //Node //r->next = NULL; //} template void LinkList template LinkList template Node Node while (p && (k != i)) { } return p; p = p->next; k++; Node front = p; p = p->next; delete front;//释放结点 Node cout << endl; cout << p->data << \" \"; p = p->next; 第14页 北京邮电大学信息与通信工程学院 template int LinkList template void LinkList template T LinkList Node if (i != 1) p = Get(i - 1);//若不是在第一个位置删除,获取第i-1个元素的地址 try { if (p && (p->next)) { Node Node if (i != 1) p = Get(i - 1); try { } catch (int i) { } cout << \"插入到位置 \" << i << \" 处\" << \"为错误位置\"< Node Node while (p&&(p->data != x)) { } return k; p = p->next; k++; 第15页 北京邮电大学信息与通信工程学院 } } } p->next = q->next; T x = q->data; delete q; return x; else throw i; catch (int i) { } cout << \"删除位置 \" << i << \" 处\" << \"为错误位置\" << endl; template int LinkList void main() { int m=1; int a[7] = { 3, 2, 1, 4, 6, 5, 7 }; LinkList cout << \"\\**************************************************\" << endl << \"\\※ ※\" << endl << \"\\※ 对该单链表的操作 ※\" << endl << \"\\※ ※\" << endl << \"\\※ 1. 获取线性表的长度 ※\" << endl << \"\\※ ※\" << endl << \"\\※ 2. 查找值为x的元素,并返回其位置 ※\" << endl << \"\\※ ※\" << endl << \"\\※ 3. 在线性表的第i个位置上插入值为x的新元素 ※\" << endl << \"\\※ ※\" << endl << \"\\※ 4. 删除线性表第i个元素,并将该元素返回 ※\" << endl << \"\\※ ※\" << endl << \"\\**************************************************\" << endl << endl; Node for (i = 0; p != NULL; i++) { } return i; p = p->next; while (m != 0) 第16页 北京邮电大学信息与通信工程学院 { cout<< \"\\\选择你需要的功能:\"; int choice; cin >> choice;//输入需要的功能 switch (choice) { case 1: { } { } { } } break; cout << \"!!无此功能项\" << endl; break; default: cout << \"请输入想要删除的元素的位置值:\" << endl; int location_3; cin >> location_3; int value_2 = list.Delete(location_3); cout << \"删除的元素值为:\" << value_2 << endl; break; case 4:// 删除线性表第i个元素,并将该元素返回 cout << \"请输入想插入的位置值:\" << endl; int location_2;//位置值 cin >> location_2; cout << \"请输入想插入的新元素的值\" << endl; int value_1;//元素值 cin >> value_1; list.Insert(location_2, value_1); cout << \"执行插入操作后的链表为:\" << endl; list.PrintList(); break; case 3://在线性表的第i个位置上插入值为x的新元素 cout << \"请输入想查找的元素的值:\" << endl; int value; cin >> value; int location = list.Locate(value); cout << \"该元素的位置为:\" << location << endl; cout << \"线性表的长度为:\" << list.GetLength()< 第17页 北京邮电大学信息与通信工程学院 } } cout << \" ※※※ 那您是否想继续?继续请输入 1 不想继续请输入 0 ※※※\" << cin >> m; endl; 第18页 因篇幅问题不能全部显示,请点此查看更多更全内容