线性表的合并
初始条件:线性表la和lb
算法:
依次从lb中取出元素,查看是否存在la中,不存在则插入
顺序线性表的实现:
//线性表的合并
void unionList(SqList* &la,SqList* &lb){
//从一个表中获取元素,再和另一个表中的数据进行比较
int lena,lenb;
lena=GetLength(la);
lenb=GetLength(lb);
for(int i=1;i<=lena;i++){
ElemType e;
GetElem(la,i,e);
if(!LocateElem(lb,e)){
ListInsert(lb,++lenb,e);
}
}
}
单链表表示的顺序表合并:
//线性表的合并,排除相同元素
void unionLink(LinkList &la,LinkList &lb){
Lnode *pa,*pb;
pa=la;
pb=lb;
int lena;
getLinkLength(la,lena);
int lenb;
getLinkLength(lb,lenb);
ElemType r;
//从一个里面拿出数据,看一下另一个里面是否含有该数据
for(int i=1;i<=lenb;i++){
getElemI(lb,i,r);//得到数据r
if(!LocteElemE(la,r)){
insertLink(la,++lena,r);
}
}
}
算法的时间复杂度都是一样的:O(length(la)*length(lb))
完整代码:
#include <iostream>
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define INFEASIBLE -1
#define OVERFLOW -2
#define MAXSIZE 100
using namespace std;
typedef int Status;//返回值类型
typedef char ElemType;//状态
typedef struct
{
ElemType elem[MAXSIZE];//对应方式二初始化
//ElemType* elem;对应方式一初始化
int length;
}SqList;
Status InitList2(SqList* &L){//改变形参中的内容并且使用它则需要用引用,解析:https://blog.youkuaiyun.com/eye123456789/article/details/79794461
//L.elem = (ElemType *)malloc(MAXSIZE * sizeof(ElemType));
L=(SqList*)malloc(sizeof(SqList));//(SqList *)表示把这个指针转型为SqlList结构的指针
//L=new SqList;也可以实现
if(!L->elem){exit(OVERFLOW);}
L->length=0;
return OK;
}
Status InitList(SqList &L){
//L.elem = (ElemType *)malloc(MAXSIZE * sizeof(ElemType));
//L.elem=new ElemType[MAXSIZE];
//开辟一个存储空间,并把这块存储空间的基地址赋值给elem
if(!L.elem){exit(OVERFLOW);}
L.length=0;
return OK;
}
void DestoryList(SqList* &L){
//注意malloc用free,new用delete
if(L) free(L);
//delete L;
}
void ClearList(SqList* &L){
L->length=0;
}
int GetLength(SqList* L){
return L->length;
}
int IsEmpty(SqList* L){
if(L->length==0) return 1;
else return 0;
}
//取线性表中i号元素
int GetElem(SqList* L,int i,ElemType &e){
if(i<1||i>L->length) return ERROR;
e=L->elem[i-1];
return OK;
}
//查找算法
int LocateElem(SqList* L,ElemType &e){
for(int i=0;i<L->length;i++){
if(L->elem[i]==e){
return ++i;
}
}
return 0;
}
Status AddElem(SqList* &L,ElemType e){
if(L->length==MAXSIZE) return ERROR;
L->elem[L->length++]=e;
return OK;
}
Status ListInsert(SqList* &L,int i,ElemType e){
if(i<1||i>(L->length+1)){
return ERROR;
}
if(L->length==MAXSIZE) return ERROR;
for(int j=L->length-1;j>=i-1;j--){
L->elem[j+1]=L->elem[j];
}
L->elem[i-1]=e;
L->length++;
return OK;
}
void selectList(SqList* L){
for(int i=0;i<L->length;i++){
printf("%c ",L->elem[i]);
}
}
Status ListDelete(SqList* &L,int i,ElemType &e){
if(i<1||i>L->length) return ERROR;
e=L->elem[i-1];
for(int j=i-1;j<L->length;j++){
L->elem[j]=L->elem[j+1];
}
L->length--;
return OK;
}
//线性表的合并
void unionList(SqList* &la,SqList* &lb){
//从一个表中获取元素,再和另一个表中的数据进行比较
int lena,lenb;
lena=GetLength(la);
lenb=GetLength(lb);
for(int i=1;i<=lena;i++){
ElemType e;
GetElem(la,i,e);
if(!LocateElem(lb,e)){
ListInsert(lb,++lenb,e);
}
}
}
//有序表的合并——顺序实现
SqList* mergeList(SqList* &la,SqList* &lb){
SqList* lc;
InitList2(lc);
int lena,lenb,pa_last=0,pb_last=0;
lena=la->length;
lenb=lb->length;
while(pa_last<lena&&pb_last<lenb){
if(la->elem[pa_last]<lb->elem[pb_last]){
lc->elem[lc->length++]=la->elem[pa_last++];
}else{
lc->elem[lc->length++]=lb->elem[pb_last++];
}
}
while(pa_last<lena){
lc->elem[lc->length++]=la->elem[pa_last++];
}
while(pb_last<lenb){
lc->elem[lc->length++]=lb->elem[pb_last++];
}
return lc;
}
int main()
{
SqList* L;
InitList2(L);
//printf("长度为:%d",L->length);
ElemType e='a';
AddElem(L,e);
AddElem(L,'c');
AddElem(L,'d');
AddElem(L,'f');
selectList(L);
printf("\n===============\n");
SqList* Lb;
InitList2(Lb);
//printf("长度为:%d",L->length);
AddElem(Lb,e);
AddElem(Lb,'e');
AddElem(Lb,'f');
AddElem(Lb,'g');
selectList(Lb);
printf("\n===============\n");
//unionList(L,Lb);
SqList* lc=mergeList(L,Lb);
selectList(lc);
printf("\n===============\n");
//selectList(L);
//printf("\n");
//ListInsert(L,2,'b');
//ElemType r;
// ListDelete(L,4,r);
// selectList(L);
// printf("\n被删除元素为:%c",r);
//ElemType r;
//GetElem(L,1,r);
//printf("a:%c\n",r);
//printf("%d",LocateElem(L,e));
//printf("%d",IsEmpty(L));
return 0;
}
链表实现的完整代码:
#include <iostream>
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define INFEASIBLE -1
#define OVERFLOW -2
#define MAXSIZE 100
using namespace std;
typedef int Status;//返回值类型
typedef char ElemType;//数据类型
using namespace std;
typedef struct Lnode{
ElemType data;
Lnode* next;
}Lnode,*LinkList;
//带头结点链表初始化
//1.将链表指向头结点,并且头结点的下一个指向为空
Status initList(LinkList &L){
//Lnode L=new Lnode;//c++语法用delete销毁,c的语法为;用free销毁
L=(LinkList)malloc(sizeof(Lnode));
L->next=nullptr;
return OK;
}
//判断链表是否为空
int isEmpty(LinkList L){
if(L->next!=nullptr) return 0;
else return 1;
}
//销毁单链表
void destoryLink(LinkList &L){
LinkList p;
//注意点:L->next=null时是最后一个节点,不是循环结束的条件
//循环结束的条件为L=null;
//while(L!=nullptr){
// p=L;
// L=L->next;
// free(p);
//}
//或者
p=L;
//这里的循环结束的条件为L=null或者p=null
while(p){
L=L->next;
free(p);
p=L;
}
}
//清空链表(头结点保存,从首元结点开始删除)
Status clearLink(LinkList &L){
LinkList pre,cur;
// if(L->next!=nullptr){
// pre=L->next;
// cur=pre->next;
// while(cur){
// free(pre);
// pre=cur;
// cur=cur->next;
// }
//}
pre=L->next;
while(pre){
cur=pre->next;
free(pre);
pre=cur;
}
L->next=nullptr;//头结点的指针域设置为空
return OK;
}
//求单链表的表长
void getLinkLength(LinkList L,int &len){
LinkList p;
p=L->next;
len=0;//设置初值
while(p!=nullptr){
len++;
p=p->next;
}
}
//取第i个元素值
Status getElemI(LinkList &L,int i,ElemType &e){
int index=1;
Lnode* p;
p=L->next;//首元结点,所以index从1开始
//如果一开始j>i说明要找的位置i比1小,是非法的
while(p&&index<i){
p=p->next;
index++;
}
if(!p||index>i) return ERROR;
e=p->data;
return ERROR;
}
//按值查找,返回地址
Lnode* LocteElemE(LinkList L,ElemType e){
Lnode* p;
p=L->next;
while(p&&p->data!=e){
p=p->next;
}
return p;
}
//按值查找,返回在第几个
int LocateElemE2(LinkList L,ElemType e){
int i=1;
Lnode* p;
p=L->next;
while(p&&p->data!=e){
p=p->next;
i++;
}
if(p==nullptr) return 0;
else return i;
}
Status insertLink(LinkList &L,int i,ElemType e){
Lnode* p=L;
int index=0;
while(p&&index<(i-1)){
p=p->next;
index++;
}
if(!p||index>i-1){//!p说明大于表长+1;index>i-1说明小于1
return ERROR;
}else{
Lnode* s=(LinkList)malloc(sizeof(Lnode));
s->data=e;
s->next=p->next;
p->next=s;
return OK;
}
}
Status deleteLink(LinkList &L,int i,ElemType &e){
int index=0;
Lnode* p;
p=L;
//或者需要用中间变量存储p->next
//Lnode* q;
while(p&&index<(i-1)){//index=i-1或者p为空的时候跳出循环
p=p->next;
index++;
}
if(p||index>(i-1)){
return ERROR;
}else{
//q=p->next;
//p->next=q->next;
//e=q->data;
e=p->next->data;
p->next=p->next->next;
return OK;
}
}
//头插法
void headInsert(LinkList &L,ElemType e){
Lnode* p=(LinkList)malloc(sizeof(Lnode));
//或者用户输入这个元素的值
//cin>>e;
//scanf(e);
p->data=e;
p->next=L->next;//原来的接在新节点的后面
L->next=p;//新节点接在头结点的后面
}
//尾插法
void tailInsert(LinkList &L,int n){
Lnode* tail;
tail=L;//指向头结点
while(n!=0){
Lnode* p=new Lnode;//记得每次都要开辟一块空间,否则输入会产生错误
cin>>p->data;
p->next=nullptr;//新指针的下一个指针域设置为空
tail->next=p;//把尾指针的下一个指向当前的新指针
tail=p;//移动尾指针的位置
n--;//减少
}
}
//遍历链表
void selectLink(LinkList L){
Lnode* p;
p=L->next;
if(p==nullptr){
printf("这个链表是空的!");
}
while(p!=nullptr){
printf("p->data: %c\n",p->data);
p=p->next;
}
}
//线性表的合并,排除相同元素
void unionLink(LinkList &la,LinkList &lb){
Lnode *pa,*pb;
pa=la;
pb=lb;
int lena;
getLinkLength(la,lena);
int lenb;
getLinkLength(lb,lenb);
ElemType r;
//从一个里面拿出数据,看一下另一个里面是否含有该数据
for(int i=1;i<=lenb;i++){
getElemI(lb,i,r);//得到数据r
if(!LocteElemE(la,r)){
insertLink(la,++lena,r);
}
}
}
//有序表的合并
void mergeLink(LinkList &la,LinkList &lb){
Lnode* lc,*pa,*pb,*pc;
lc=la;
pc=lc;
pa=la->next;
pb=lb->next;
while(pa!=nullptr&&pb!=nullptr){
if(pa->data>=pb->data){
pc->next=pb;
pb=pb->next;
pc=pc->next;
}else{
pc->next=pa;
pa=pa->next;
pc=pc->next;
}
}
pc->next=pa?pa:pb;//三目运算符
delete lb;
}
int main()
{
//LinkList L;
//initList(L);
//ElemType elem[5]={'a','b','c','d','e'};
//for(int i=4;i>=0;i--){
// headInsert(L,elem[i]);
//}
//tailInsert(L,5);
//selectLink(L);
//insertLink(L,6,'f');
//printf("插入后:\n");
//ElemType result;
// getElemI(L,5,result);
//printf("取出第5个元素的值为%c\n",result);
//Lnode* p=LocteElemE(L,'a');
//printf("按值查找返回地址:%c\n",p->data);
//int i=LocateElemE2(L,'a');
// printf("按值查找返回第几个: %d\n",i);
// selectLink(L);
//int len;
//getLinkLength(L,len);
//printf("链表长度:%d\n",len);
//==========================下面测试线性表的合并
LinkList la,lb;
initList(la);
initList(lb);
tailInsert(la,5);
selectLink(la);
tailInsert(lb,5);
selectLink(lb);
//unionLink(la,lb);
//printf("======合并后数据=======\n");
//selectLink(la);
mergeLink(la,lb);
printf("========有序表的合并======\n");
selectLink(la);
return 0;
}