目录
PPT:第二章P173;
并集集合:线性表的合并(无需有序,不能重复)
线性表:
Status Union(Sqlist& A, Sqlist& B)//并集
{
int len_A = A.length;
int len_B = B.length;
for (int i = 1; i <= len_B; i++)
{
Poly e=*A.elem;
//这里只是给我们设定的元素e赋一个任意初值
//只要保证e在初始化时由初值不为空即可
//至于该e元素的内容是什么其实并没有什么所谓
//因为后面我们总归是会改的
GetElem(B, i, e);
if (LocateElem(A, e))
return ERROR;
else
ListInsert(A, ++len_A, e);
//注意插入函数中输入的是位序,不是数组下标
}
return true;
}
该算法的时间复杂度:O(ListLenth(La) * ListLength(Lb))
最后A表为合并以后的新表
链表:
Status Union(Lnode& A, Lnode& B)
{
for (int i = 1; i <= 求表长(&B); i++)
{
int len_A = 求表长(&A);
Elemtype e;
取第i个元素(&A, i, e);
if (!LocateELem(&B, e))
Listlnsert(&A, ++len_A, e);
}
return true;
}
结果:(默认在(7):小结:关于链表和线性表的定义及操作当中预设的前置语句之下运行)
而产生该结果的原因,和前置语句中,定义插入函数的语句有关:
Status Listlnsert(LinkList& L, int i, Elemtype e)
更准确的来说:问题源于我们给出的 “&A”和定义中的“LinkList& L”类型匹配不上
这里,我们对LinkList &A等格式进行一个系统性的总结:
&A代表的到底是什么??
Sqlist A:线性表结点类型的变量A
Sqlist &A:还是表示线性表结点类型的变量A,但是(只是)表示采用引用传值的传值方式
LinkList A:指向目标对象为 线性表结点类型的指针变量ALinkList &A:还是表示指向目标对象为 线性表结点类型的指针变量A
只是
表示采用引用传值的传值方式传达(递)这个地址
想要程序能够正常运行,改动的方法有两种:
1:
修改<插入>函数的函数体:(此时<合并>函数无需修改)
把合并函数的“声明”(函数体之外)部分改为:
Status Listlnsert(LinkList L, int i, Elemtype e)
此时,该合并函数所需要的前置条件(最简单版本)为:
//链表的定义及其基础操作
#include<iostream>
using namespace std;
#include<stdlib.h>//存放exit
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define INFEASIBLE -1
#define OVERFLOW -2
#define MAXlength 100 //初始大小为100,可按需修改
typedef int Status; //函数调用状态
struct K
{
float a;
int b;
string c;
bool operator==(K& t)
{
return t.a == a && t.b == b;
//&& t.c = c;
}
bool operator!=(K& t)
{
return t.a != a || t.b != b;
//|| t.c = c;
}
};
typedef K Elemtype; //函数调用状态
struct Lnode
//node:结; 结点;
{
Elemtype data;
Lnode* next;
};
typedef Lnode* LinkList;
Status 链表是否为空(LinkList L)
{
if (L->next)
return true;
else
return false;
}
Status 求表长(LinkList L)
{
if (链表是否为空(L))
cerr << "链表为空" << endl;
LinkList p = L->next;
//特别注意:因为这里从首元结点开始算起(计算)
//所以:L->next;
int i = 0;
while (p)//不要写成if
{
p = p->next;
i++;
}
//cout << "表长为: " << i << endl;
return i;
}
Status 取第i个元素(LinkList L, int i, Elemtype e)
{// GetElem“i”
LinkList p;
p = L->next;
int j = 1;
while (p && i > j)
{
p = p->next;
j++;
}
if (i < 0 || i < j || !p)
return false;
e = p->data;
return true;
}
Status LocateELem(LinkList L, Elemtype e)
{
//在线性表L中查找值为e的数据元素
//找到,则返回L中值为e的数据元素的地址,查找失败返回NULL
auto p = L->next; int i = 1;
while (p && p->data != e)
{
i++;
if (e == p->data)
{
cout << "地址为: " << p << ";" << endl;
cout << "位置序号为: " << i << ";" << endl;
}
p = p->next;
}
if (p == NULL)
return NULL;
return true;
}
Status Listlnsert(LinkList L, int i, Elemtype e)
{//插入(把元素e插到第i个位置结点上)
auto p = L; int j = 0;
while (p && j < i - 1)
{
p = p->next; ++j;
}
if (!p || j > i - 1)
return false;
auto s = new Lnode;
s->data = e;
s->next = p->next;
p->next = s;
return true;
}//Listlnsert_L
2:
修改<合并>函数的函数体:(在前置语句保持不变,不必改动的情况下)
Status Union(Lnode& A, Lnode& B)
{
for (int i = 1; i <= 求表长(&B); i++)
{
int len_A = 求表长(&A);
Elemtype e;
LinkList p = &A;
取第i个元素(&A, i, e);
if (!LocateELem(&B, e))
Listlnsert(p, ++len_A, e);
}
return true;
}
那么此时,一个让我觉得很有意思(很奇怪)的现象(情况)就发生了
问题:
为什么在前面“&A”和定义中的“LinkList& L”类型匹配不上
但是只要我们把“&A”放到一个新的该类型的变量当中,让该信息以变量的形式在程序中执行
放进去的明明都是同一个东西(&A),凭什么(怎么)原来的时候程序就可以运行了呢???