有序表的合并
初始条件:la和lb中的元素按值非递减排序
要求:合并到lc,lc依然是按值非递减
顺序表实现
#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;//对应方式二初始化
//ElemType* elem;对应方式一初始化
int length;
}SqList;
Status init(SqList &L){
L.elem=new ElemType[MAXSIZE];
if(!L.elem) return ERROR;
L.length=0;
return OK;
}
void mergeList(SqList la,SqList lb,SqList &lc) {
ElemType *pa,*pb,*pa_last,*pb_last,*pc;
pa=la.elem;
pb=lb.elem;
pc=lc.elem;
int lena=la.length;
int lenb=lb.length;
lc.length=lena+lenb;
pa_last=la.elem+lena-1;
pb_last=lb.elem+lenb-1;
while(pa<=pa_last&&pb<=pb_last){
if(*pa<=*pb){
*pc++=*pa++;
}else{
*pc++=*pb++;
}
}
while(pa<=pa_last){
*pc++=*pa++;
}
while(pb<=pb_last){
*pc++=*pb++;
}
}
int main()
{
SqList la,lb,lc;
init(la);
init(lb);
init(lc);
for(int i=0;i<5;i++){
cin>>la.elem[la.length++];
}
for(int i=0;i<5;i++){
cin>>lb.elem[lb.length++];
}
for(int i=0;i<5;i++){
printf("la中数据:%c\n",la.elem[i]);
}
printf("====================================\n");
for(int i=0;i<5;i++){
printf("lb中数据:%c\n",lb.elem[i]);
}
mergeList(la,lb,lc);
printf("====================================\n");
for(int i=0;i<lc.length;i++){
printf("lc中数据:%c\n",lc.elem[i]);
}
return 0;
}
链表实现
核心代码:
//有序表的合并
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;
}
完整代码:
#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;
}
时间复杂度是:O(length(la)+length(lb))