Loading... <div class="tip inlineBlock warning"> 本文为本人按照书本要求所写作业,算法并非最优,仅供参考 </div> # 试验2.2 有序表合并 姓名:郁闷的酱油瓶 班级:软工 学号:47 试验时间:2021.10.9 ## 1.问题描述 把两个有序表并为一个有序表 ## 2.数据结构设计 ### (1)结构设计 考虑到无序输入,使用有头结点的单链表 ```c++ //LinkList.h template<class T> struct Node { T data; //数据域 Node* next; //指针域 }; ``` ### (2)函数设计 所需要函数为 构造函数,创建链表,输出链表元素,合并链表 ```c++ //LinkList.h template<class T> class LinkList { private: Node<T>* Head; //链表头节点 public: LinkList(); //构造函数,创建空链表 void CreatList(int n); //创建具有n个元素的线性链表 void ListDisplay(); //输出元素表 void MergeList(LinkList<T> La, LinkList<T> Lb); //合并 }; ``` ## 3.算法设计 ### (1)输入集合 从键盘输入,先输入个数,再输入数据 ```c++ //LinkList.h //构造空链表 LinkList<int>La; LinkList<int>Lb; LinkList<int>Lc; //创建表 int n; cout << "请输入顺序表SA元素个数:"; cin >> n; cout << endl; try { La.CreatList(n); } catch (char* err) { cout << err << endl; } cout << "请输入顺序表SB元素个数:"; cin >> n; cout << endl; try { Lb.CreatList(n); } catch (char* err) { cout << err << endl; } ``` ### (2)合并算法 ### Step 1: 初始化 ```c++ //LinkList.h template<class T> void LinkList<T>::MergeList(LinkList<T> LA, LinkList<T> LB) ``` #### 1.1 设置工作指针pa、pb,分别指向两个有序表LA、LB。 ```c++ Node<T>* pa, * pb; pa = LA.Head->next; pb = LB.Head->next; ``` #### 1.2 生成新表LC的头结点,链到LC表尾,pc指向它。 ```c++ Node<T>* pc; pc = Head; ``` ### Step 2: 只要pa和pb有所指,循环执行下列操作 ```c++ while (pa && pb) ``` #### 2.1 生成一个新结点,链到LC表尾,pc指向它 ```c++ Node<T>* p=new Node<T>; p->next = NULL; pc->next = p; pc = p; ``` #### 2.2 如果pa->data<=pb->data 执行pa->data=pa->data;pa后移 ```c++ if (pa->data <= pb->data) { pc->data = pa->data; pa = pa->next; } ``` #### 2.3 否则:pc->data=pb->data; pb后移 ```c++ else { pc->data = pb->data; pb = pb->next; } ``` ### Step 3: 如果pa空,把pb开始的结点一次复制到pc后 ```c++ if (pa == NULL) { while (pb) { Node<T>* p2=new Node<T>; p2->next = NULL; pc->next = p2; pc = p2; pc -> data = pb->data; pb = pb->next; } } ``` ### Step 4: 如果pb空,把pa开始的结点一次复制到pc后 ```c++ else if (pb == NULL) { while (pa) { Node<T>* p3=new Node<T>; p3->next = NULL; pc->next = p3; pc = p3; pc -> data = pa->data; pa = pa->next; } } ``` ### (3)调用并输出 ```c++ //main.cpp Lc.MergeList(La, Lb); cout<<"SC:"<<endl; Lc.ListDisplay(); ``` ## 4.运行和测试 1. 测试1: (1)运行程序 (2)输入SA元素个数 (3)输入SA元素  (4)输入SB元素个数  (5)输入SB元素  (6) 输出SC  2. 测试2: 3. 测试3: 4. 测试4: 5. 测试5: 6. 测试6: 7. 测试7: ## 5.调试记录及收获 附1:源程序清单 ```c++ //LinkList.h #pragma once #include<iostream> using namespace std; template<class T> struct Node { T data; //数据域 Node* next; //指针域 }; template<class T> class LinkList { private: Node<T>* Head; //链表头节点 public: LinkList(); //构造函数,创建空链表 void CreatList(int n); //创建具有n个元素的线性链表 void ListDisplay(); //输出元素表 void MergeList(LinkList<T> La, LinkList<T> Lb); //合并 }; //构造函数,创建空链表 template<class T> LinkList<T>::LinkList() { Head = new Node<T>; Head->next = NULL; } //创建具有n个元素的线性链表 template<class T> void LinkList<T>::CreatList(int n) { Node<T>* p, * s; p = Head; cout << "请依次输入" << n << "个元素值:" << endl; for (int i = 1; i <= n; i++) { s = new Node<T>; cin >> s->data; s->next = p->next; p->next = s; p = s; } } //输出元素表 template<class T> void LinkList<T>::ListDisplay() { Node<T>* p; p = Head->next; int i = 1; while (p) { cout << i << "\t"; cout << p->data << endl; p = p->next; i++; } } template<class T> void LinkList<T>::MergeList(LinkList<T> LA, LinkList<T> LB) { Node<T>* pa, * pb; pa = LA.Head->next; pb = LB.Head->next; Node<T>* pc; pc = Head; while (pa && pb) { Node<T>* p=new Node<T>; p->next = NULL; pc->next = p; pc = p; if (pa->data <= pb->data) { pc->data = pa->data; pa = pa->next; } else { pc->data = pb->data; pb = pb->next; } } if (pa == NULL) { while (pb) { Node<T>* p2=new Node<T>; p2->next = NULL; pc->next = p2; pc = p2; pc -> data = pb->data; pb = pb->next; } } else if (pb == NULL) { while (pa) { Node<T>* p3=new Node<T>; p3->next = NULL; pc->next = p3; pc = p3; pc -> data = pa->data; pa = pa->next; } } } ``` ```c++ //main.cpp #include<iostream> #include"LinkList.h" using namespace std; typedef int T; //有序表合并 int main() { //构造空链表 LinkList<int>La; LinkList<int>Lb; LinkList<int>Lc; //创建表 int n; cout << "请输入顺序表SA元素个数:"; cin >> n; cout << endl; try { La.CreatList(n); } catch (char* err) { cout << err << endl; } cout << "请输入顺序表SB元素个数:"; cin >> n; cout << endl; try { Lb.CreatList(n); } catch (char* err) { cout << err << endl; } Lc.MergeList(La, Lb); cout<<"SC:"<<endl; Lc.ListDisplay(); } ``` # 试验2.3 集合交运算问题 姓名:郁闷的酱油瓶 班级:软工 学号:47 试验时间:2021.10.9 ## 1.问题描述 用线性表表示两个集合,求两个集合的交集。 ## 2.数据结构设计 ### (1)结构设计 考虑到集合的插入和删除,使用有头节点的单链表 ```c++ //LinkList.h template<class T> struct Node { T data; //数据域 Node* next; //指针域 }; ``` ### (2)函数设计 需要用到构造函数,析构函数,创建单链表,删除元素,查找元素,获取元素,测表长,输出元素表 ```c++ //LinkList.h template<class T> class LinkList { private: Node<T>* Head; //链表头节点 public: LinkList(); //构造函数,创建空链表 ~LinkList(); //析构函数,删除表空间 void CreatList(int n); //创建具有n个元素的线性链表 T Delete(int i); //删除表中的第i个元素 T GetElem(int i); //获取第i个元素的值 int Locate(T e); //在链表种查找值为e的元素 int Length(); //测表长 void SetDisplay(); //以集合形式输出元素表 }; ``` ## 3.算法设计 ### (1)数据输入 从键盘输入La与Lb的元素 ```c++ //main.cpp //构造空链表 LinkList<char>La; LinkList<char>Lb; //创建表 int n; cout << "请输入顺序表La元素个数:"; cin >> n; cout << endl; try { La.CreatList(n); } catch (char* err) { cout << err << endl; } cout << "请输入顺序表Lb元素个数:"; cin >> n; cout << endl; try { Lb.CreatList(n); } catch (char* err) { cout << err << endl; } ``` ### (2)交集算法 #### step 1: 扫描A ```c++ for (int i = 1; i <= La.Length(); i++) //扫描La中的元素 ``` #### step 2: 在B中查找元素,若B中有,则保留,否则删除该节点 ```c++ if (!Lb.Locate(La.GetElem(i))) //若扫描到的元素在Lb中不存在,则删除 { La.Delete(i); //删除元素 i--; //定位-1 } ``` #### step 3: 释放B所占用的空间 ```c++ Lb.~LinkList(); ``` #### step 4: 显示A∩B ```c++ cout << "A∩B="; La.SetDisplay(); ``` ## 4.运行和测试 #### 测试1: (1)运行程序  (2)输入集合A的元素个数  (3)输入集合A的元素  (4)输入集合B的元素个数  (5)输入集合B的元素  (6)得到A∩B  #### 测试2: #### 测试3:  #### 测试4:  ## 5.调试记录与收获 附1:源程序清单 ```c++ //LinkList.h #pragma once #include<iostream> using namespace std; template<class T> struct Node { T data; //数据域 Node* next; //指针域 }; template<class T> class LinkList { private: Node<T>* Head; //链表头节点 public: LinkList(); //构造函数,创建空链表 ~LinkList(); //析构函数,删除表空间 void CreatList(int n); //创建具有n个元素的线性链表 T Delete(int i); //删除表中的第i个元素 T GetElem(int i); //获取第i个元素的值 int Locate(T e); //在链表种查找值为e的元素 int Length(); //测表长 void SetDisplay(); //以集合形式输出元素表 }; //函数的实现 //构造函数,创建空链表 template<class T> LinkList<T>::LinkList() { Head = new Node<T>; Head->next = NULL; } //析构函数,删除表空间 template<class T> LinkList<T>::~LinkList() { Node<T>* p; while (Head) { p = Head; Head = Head->next; delete p; } Head = NULL; } //创建具有n个元素的线性链表 template<class T> void LinkList<T>::CreatList(int n) { Node<T>* p, * s; p = Head; cout << "请依次输入" << n << "个元素值:" << endl; for(int i=1;i<=n;i++) { s = new Node<T>; cin >> s->data; s->next = p->next; p->next = s; p = s; } } //删除表中的第i个元素 template<class T> T LinkList<T>::Delete(int i) { T x; Node<T>* p, * q; p = Head; int j = 0; while (p->next && j < i - 1) { p = p->next; j++; } if (!p->next || j > i - 1) throw"位置异常"; else { q = p->next; p->next = q->next; x = q->data; delete q; return x; }; } //获取第i个元素的值 template<class T> T LinkList<T>::GetElem(int i) { Node<T>* p; p = Head->next; int j = 1; while (p&&j<i) { p = p->next; j++; } if (!p || j > i) throw"位置"; else return p->data; } //在链表种查找值为e的元素 template<class T> int LinkList<T>::Locate(T e) { int j = 1; Node<T>* p; p = Head->next; while (p && p->data != e) { p = p->next; j++; } if (p == NULL) return 0; else return j; } //测表长 template<class T> int LinkList<T>::Length() { int len = 0; Node<T>* p; p = Head; while (p->next) { len++; p = p->next; } return len; } //以集合形式输出 template<class T> void LinkList<T>::SetDisplay() { Node<T>* p; p = Head->next; int i = 1; cout << "{"; while (p) { cout << p->data << ", "; p = p->next; i++; } cout << "}"; } ``` ```c++ //main.cpp #include<iostream> #include"LinkList.h" using namespace std; typedef char T; //2.3集合交运算问题 int main() { //构造空链表 LinkList<char>La; LinkList<char>Lb; //创建表 int n; cout << "请输入顺序表La元素个数:"; cin >> n; cout << endl; try { La.CreatList(n); } catch (char* err) { cout << err << endl; } cout << "请输入顺序表Lb元素个数:"; cin >> n; cout << endl; try { Lb.CreatList(n); } catch (char* err) { cout << err << endl; } for (int i = 1; i <= La.Length(); i++) //扫描La中的元素 { if (!Lb.Locate(La.GetElem(i))) //若扫描到的元素在Lb中不存在,则删除 { La.Delete(i); //删除元素 i--; //定位-1 } } //释放表Lb Lb.~LinkList(); //输出交集 cout << "A∩B="; La.SetDisplay(); } ``` 最后修改:2022 年 06 月 03 日 © 允许规范转载 打赏 赞赏作者 支付宝微信 赞 如果觉得我的文章对你有用,请随意赞赏