一、线性表的合并:
假设利用两个线性表La,Lb分别表示两个集合a,b,求这a∪b.
算法步骤:
依次取出Lb中的每个元素,执行以下操作:
① 在La中查找该元素
②如果找不到,则把这个元素插入到La的最后。
void union( List &La, List Lb) {
La_len=ListLength(La);
Lb_len=ListLength(Lb);
for(i=1: i<=Lb len; i++){
GetElem(Lb, i, e);//依次看看Lb中每个值又没有在La中有,没有就插入La
if(!Locate Elem(La, e)) Listinsert(&La, ++La len, e);
}
}
完整代码:
#include <iostream>
using namespace std;
#define OK 1
#define ERROR 0
typedef struct Node{
int data;
struct Node *next;
}node, *linklist;
int len(linklist L);
int get_elem(linklist L, int i);
int check_elem(linklist L, int e);
void insert_elem(linklist &L, int e);
void create(linklist &L, int n);
int main()
{
linklist L, M;
create(L, 4);
create(M, 3);
int i, j, k;
for (i = 1; i <= len(M); ++i){
int temp = get_elem(M, i);
if (!(check_elem(L, temp))) insert_elem(L, temp);
}
linklist p = L->next;
while(p){
printf("%d ", p->data);
p = p->next;
}
return 0;
}
void create(linklist &L, int n){
L = new Node;
L->next = NULL;
linklist r = L;
int i;
for (i = 0; i < n; ++i){
linklist p = new Node;
cin >> p->data;
p->next = NULL;
r->next = p;
r = p;
}
}
int len(linklist L){
linklist p = L->next;
int j = 0;
while(p){
p = p->next;
++j;
}
return j;
}
int get_elem(linklist L, int i){
linklist p = L->next;
int j = 1;
while(p && j<i){
p = p->next;
++j;
}
if (!p || j>i)return ERROR;
return p->data;
}
int check_elem(linklist L, int e){
linklist p = L->next;
while(p && p->data != e){
p = p->next;
}
if (!p) return 0;
else return OK;
}
void insert_elem(linklist &L, int e){
linklist p = new Node, r = L->next;
p->next = NULL;
p->data = e;
while(r->next) r = r->next;
r->next = p;
}
二、有序表的合并:
已知线性表La和Lb中的数据元素按值非递减有序排列,现要求将La和Lb归并为一个新的线性表Lc,且Lc中的数据元素仍按值非递减有序排列。
算法步骤:
①创建空表Lc
②依次从La或Lb中摘取元素值较小的结点插入Lc表的最后,直至其中一个表变空为止
③继续将La或Lb其中一个表的剩余结点插入在Lc的最后
1.顺序表
void MergeList_Sq(SqList LA, SqList LB, SqList &LC) {
pa = LA.elem;
pb = LB.elem; //指针pa和pb的初值分别指向两个表的第一个元素(基地址)
LC.length = LA.length + LB.length; //新表长度为待合并两表的长度之和
LC.elem = new ElemType[LC.length]; //为合并后的新表分配一个数组空间
pc = LC.elem; //指针pc指向新表的第一个元素
pa_last = LA.elem + LA.length - 1; //指针pa_last指向LA的最后一个元素
pb_last = LB.elem + LB.length - 1; //指针pb_last指向LB的最后一个元素
while (pa <= pa_last && pb <= pb_last) { //两个表都非空
if (*pa <= *pb) *pc++ = *pa++; //依次“摘取”两表中值较小的结点
else *pc++ = *pb++;
}
while (pa <= pa_last) *pc++ = *pa++;//B表已到达表尾,将LA中剩余元素加入LC
while (pb <= pb_last) *pc++ = *pb++;//A表已到达表尾,将LB中剩余元素加入LC
}
//循环的次数取决于LA,LB中数据的元素多少,Lc的长度取决于LA,LB中数据的元素多少
//时间复杂度和空间复杂度都是O(ListLength(La)+ListLength(Lb))
2.链表:
void MergeList L(LinkList &La, LinkList &Lb, LinkList &Lc) {
pa = La->next; pb = Lb->next;
pc = Lc = La; //用La的头结点作为Lc的头结点
while (pa && pb) {
if (pa->data <= pb->data) {pc->next = pa; pc = pa; pa = pa->next;}
else {pc->next = pb; pc = pb; pb = pb->next;}
}
pc->next = pa ? pa : pb;//插入剩余段
delete Lb;//释放Lb的头结点
}
//时间复杂度最坏情况是La,Lb轮流出现要加入的元素,必须要La,Lb中每一个元素都要走一遍,即O(ListLength(La)+ListLength(Lb))
//在原有链表基础上操作,不需要额外空间,因此空间复杂度是O(1)
三、一元多项式的运算(加法)
1.一般多项式(建议用顺序表实现)
2.稀疏多项式(建议用链表实现,因为不需要存入0,节省了内存空间)
typedef struct PNode{
float coef;
int expn;
struct PNode *next;
}PNode, *Polynomial;
建立多项式链表:
void Create Polyn(Polynomial &P, int n){
//输入m项的系数和指数,建立表示多项式的有序链表P
P = new PNode;
P->next = NULL; //先建立一个带头结点的单链表
for (i = 1;i <= n; ++i){ //依次输入n个非零项
s = new PNode;//生成新结点
cin >> s->coef >> s->expn;//输入系数和指数
pre = P;//pre用于保存q的前驱,初值为头结点
q = P->next; //q初始化,指向首元结点
while (q && q->expn < s->expn){//找到第一个大于输入项指数的项"q
pre = q;
q = q->next;
}
s->next = q; //将输入项s插入到q和其前驱结点pre之间
pre->next = s;
}
}
多项式相加:
typedef struct Node
{
int coef;//coefficient:系数
int index;//index:指数
struct Node *next=NULL;
}node;
//多项式相加算法
node *addpolylist(node *la,node *lb, node &lb)//polynomial:多项式
{
node temp = new node;
node *pa, *pb, *pc;
lc = la; //以la的头结点作为lc的头结点
pa = la->next; pb = lb->next; pc = lc;//将pa,pb分别指向la,lb的首元结点
while (pa && pb)//分别遍历,两个链表指针非空为循环条件,就是两串都还没加完
{
if (pa->index < pb->index) //pa指向结点系数大于pb
{
pc->next = pa;
pa = pa->next;
pc = pc->next;
}
else if (pa->index > pb->index)
{
pc->next = pb;
pb = pb->next;
pc = pc->next;
}
else
{
temp = new node;
temp->coef = pa->coef + pb->coef;
if (temp->coef)//系数相加非零
{
temp->index = pa->index;
pc->next = temp;
pa = pa->next;
pb = pb->next;
pc = pc->next;
}
else
{
delete temp;
pa = pa->next;
pb = pb->next;
}
}
}
pc->next = pa ? pa : pb;//把pa或pb剩余没加完的非空列表加在pc后面
return lc;
}