-
-
-
-
-
-
-
-
- // algo2-9.cpp 尽量采用bo2-31.cpp中的基本操作实现算法2.17的功能
- #include"c1.h"
- #define N 2
- typedef char ElemType;
- #include"c2-3.h"
- #include"func2-2.cpp"
- #include"bo2-31.cpp"
- #include"func2-3.cpp" // 包括equal()、comp()、print()、print2()和print1()函数
- void difference(SLinkList space) // 改进算法2.17(尽量利用基本操作实现)
- { // 依次输入集合A和B的元素,在一维数组space中建立表示集合(A-B)∪(B-A)的静态链表
- int m,n,i,j;
- ElemType b,c;
- InitList(space); // 构造空链表
- printf("请输入集合A和B的元素个数m,n:");
- scanf("%d,%d%*c",&m,&n); // %*c吃掉回车符
- printf("请输入集合A的元素(共%d个):",m);
- for(j=1;j<=m;j++) // 建立集合A的链表
- {
- scanf("%c",&b); // 输入A的元素值
- ListInsert(space,1,b); // 插入到表头
- }
- scanf("%*c"); // 吃掉回车符
- printf("请输入集合B的元素(共%d个):",n);
- for(j=1;j<=n;j++)
- { // 依次输入B的元素,若不在当前表中,则插入,否则删除
- scanf("%c",&b);
- for(i=1;i<=ListLength(space);i++)
- {
- GetElem(space,i,c); // 依次求得表中第i个元素的值,并将其赋给c
- if(c==b) // 表中存在b,且其是第i个元素
- {
- ListDelete(space,i,c); // 删除第i个元素
- break; // 跳出i循环
- }
- }
- if(i>ListLength(space)) // 表中不存在b
- ListInsert(space,1,b); // 将b插在表头
- }
- }
- void main()
- {
- SLinkList s;
- difference(s);
- ListTraverse(s,print2);
- }
- // algo2-10.cpp 两个仅设表尾指针的循环链表的合并(教科书图2.13)
- #include"c1.h"
- typedef int ElemType;
- #include"c2-2.h"
- #include"bo2-4.cpp"
- #include"func2-3.cpp" // 包括equal()、comp()、print()、print2()和print1()函数
- void MergeList(LinkList &La,LinkList Lb)
- { // 将Lb合并到La的表尾,由La指示新表
- LinkList p=Lb->next;
- Lb->next=La->next;
- La->next=p->next;
- free(p);
- La=Lb;
- }
- void main()
- {
- int n=5,i;
- LinkList La,Lb;
- InitList(La);
- for(i=1;i<=n;i++)
- ListInsert(La,i,i);
- printf("La="); // 输出链表La的内容
- ListTraverse(La,print);
- InitList(Lb);
- for(i=1;i<=n;i++)
- ListInsert(Lb,1,i*2);
- printf("Lb="); // 输出链表Lb的内容
- ListTraverse(Lb,print);
- MergeList(La,Lb);
- printf("La+Lb="); // 输出合并后的链表的内容
- ListTraverse(La,print);
- }
- // algo2-11.cpp 实现算法2.20、2.21的程序
- #include"c1.h"
- typedef int ElemType;
- #include"c2-5.h"
- #include"bo2-6.cpp"
- #include"func2-3.cpp" // 包括equal()、comp()、print()、print2()和print1()函数
- Status ListInsert_L(LinkList &L,int i,ElemType e) // 算法2.20
- { // 在带头结点的单链线性表L的第i个元素之前插入元素e
- Link h,s;
- if(!LocatePos(L,i-1,h))
- return ERROR; // i值不合法
- MakeNode(s,e); // 结点分配失败则退出
- InsFirst(L,h,s); // 对于从第i个结点开始的链表,第i-1个结点是它的头结点
- return OK;
- }
- void MergeList_L(LinkList &La,LinkList &Lb,LinkList &Lc,int(*compare)(ElemType,ElemType))
- { // 已知单链线性表La和Lb的元素按值非递减排列。归并La和Lb得到新的单链
- // 线性表Lc,Lc的元素也按值非递减排列。算法2.21
- Link ha,hb,pa,pb,q;
- ElemType a,b;
- InitList(Lc); // 存储空间分配失败则退出
- ha=GetHead(La); // ha和hb分别指向La和Lb的头结点
- hb=GetHead(Lb);
- pa=NextPos(ha); // pa和pb分别指向La和Lb的首元结点
- pb=NextPos(hb);
- while(pa&&pb) // La和Lb均非空
- {
- a=GetCurElem(pa); // a和b为两表中当前比较元素(第1个元素)
- b=GetCurElem(pb);
- if(compare(a,b)<=0) // a<=b
- {
- DelFirst(La,ha,q); // 移去La的首元结点并以q返回
- q->next=NULL; // 将q的next域赋值NULL,以便调用Append()
- Append(Lc,q); // 将q结点接在Lc的尾部
- pa=NextPos(ha); // pa指向La新的首元结点
- }
- else // a>b
- {
- DelFirst(Lb,hb,q); // 移去Lb的首元结点并以q返回
- q->next=NULL; // 将q的next域赋值NULL,以便调用Append()
- Append(Lc,q); // 将q结点接在Lc的尾部
- pb=NextPos(hb); // pb指向Lb新的首元结点
- }
- }
- if(pa) // La非空
- Append(Lc,pa); // 链接La中剩余结点
- else // Lb非空
- Append(Lc,pb); // 链接Lb中剩余结点
- free(ha); // 销毁La和Lb
- La.head=La.tail=NULL;
- La.len=0;
- free(hb);
- Lb.head=Lb.tail=NULL;
- Lb.len=0;
- }
- int diff(ElemType c1,ElemType c2)
- {
- return c1-c2;
- }
- void main()
- {
- LinkList La,Lb,Lc;
- int j;
- InitList(La);
- for(j=1;j<=5;j++)
- ListInsert_L(La,j,j); // 顺序插入 1、2、3、4、5
- printf("La=");
- ListTraverse(La,print);
- InitList(Lb);
- for(j=1;j<=5;j++)
- ListInsert_L(Lb,j,2*j); // 顺序插入 2、4、6、8、10
- printf("Lb=");
- ListTraverse(Lb,print);
- MergeList_L(La,Lb,Lc,diff); // 归并La和Lb,产生Lc
- printf("Lc=");
- ListTraverse(Lc,print);
- DestroyList(Lc);
- }
- // algo2-12.cpp 用单链表实现算法2.1,仅有4句与algo2-1.cpp不同
- #include"c1.h"
- typedef int ElemType;
- #include"c2-2.h" // 此句与algo2-1.cpp不同(因为采用不同的结构)
- #include"bo2-2.cpp" // 此句与algo2-1.cpp不同(因为采用不同的结构)
- #include"func2-3.cpp" // 包括equal()、comp()、print()、print2()和print1()函数
- void Union(LinkList La,LinkList Lb) // 算法2.1,此句与algo2-1.cpp不同
- { // 将所有在线性表Lb中但不在La中的数据元素插入到La中
- ElemType e;
- int La_len,Lb_len;
- int i;
- La_len=ListLength(La); // 求线性表的长度
- Lb_len=ListLength(Lb);
- for(i=1;i<=Lb_len;i++)
- {
- GetElem(Lb,i,e); // 取Lb中第i个数据元素赋给e
- if(!LocateElem(La,e,equal)) // La中不存在和e相同的元素,则插入之
- ListInsert(La,++La_len,e);
- }
- }
- void main()
- {
- LinkList La,Lb; // 此句与algo2-1.cpp不同(因为采用不同的结构)
- int j;
- InitList(La); // 创建空表La。如不成功,则会退出程序的运行
- for(j=1;j<=5;j++) // 在表La中插入5个元素
- ListInsert(La,j,j);
- printf("La= "); // 输出表La的内容
- ListTraverse(La,print);
- InitList(Lb); // 创建空表Lb
- for(j=1;j<=5;j++) // 在表Lb中插入5个元素
- ListInsert(Lb,j,2*j);
- printf("Lb= "); // 输出表Lb的内容
- ListTraverse(Lb,print);
- Union(La,Lb);
- printf("new La= "); // 输出新表La的内容
- ListTraverse(La,print);
- }
- // algo2-13.cpp 采用单链表结构实现算法2.2的程序,仅有4句与algo2-2.cpp不同
- #include"c1.h"
- typedef int ElemType;
- #include"c2-2.h" // 此句与algo2-2.cpp不同
- #include"bo2-2.cpp" // 此句与algo2-2.cpp不同
- #include"func2-3.cpp" // 包括equal()、comp()、print()、print2()和print1()函数
- void MergeList(LinkList La,LinkList Lb,LinkList &Lc) // 算法2.2,此句与algo2-2.cpp不同
- { // 已知线性表La和Lb中的数据元素按值非递减排列。
- // 归并La和Lb得到新的线性表Lc,Lc的数据元素也按值非递减排列
- int i=1,j=1,k=0;
- int La_len,Lb_len;
- ElemType ai,bj;
- InitList(Lc); // 创建空表Lc
- La_len=ListLength(La);
- Lb_len=ListLength(Lb);
- while(i<=La_len&&j<=Lb_len) // 表La和表Lb均非空
- {
- GetElem(La,i,ai);
- GetElem(Lb,j,bj);
- if(ai<=bj)
- {
- ListInsert(Lc,++k,ai);
- ++i;
- }
- else
- {
- ListInsert(Lc,++k,bj);
- ++j;
- }
- }
- while(i<=La_len) // 表La非空且表Lb空
- {
- GetElem(La,i++,ai);
- ListInsert(Lc,++k,ai);
- }
- while(j<=Lb_len) // 表Lb非空且表La空
- {
- GetElem(Lb,j++,bj);
- ListInsert(Lc,++k,bj);
- }
- }
- void main()
- {
- LinkList La,Lb,Lc; // 此句与algo2-2.cpp不同
- int j,a[4]={3,5,8,11},b[7]={2,6,8,9,11,15,20}; // 教科书例2–2的数据
- InitList(La); // 创建空表La
- for(j=1;j<=4;j++) // 在表La中插入4个元素
- ListInsert(La,j,a[j-1]);
- printf("La= "); // 输出表La的内容
- ListTraverse(La,print);
- InitList(Lb); // 创建空表Lb
- for(j=1;j<=7;j++) // 在表Lb中插入7个元素
- ListInsert(Lb,j,b[j-1]);
- printf("Lb= "); // 输出表Lb的内容
- ListTraverse(Lb,print);
- MergeList(La,Lb,Lc);
- printf("Lc= "); // 输出表Lc的内容
- ListTraverse(Lc,print);
- }
- #include"c1.h"
- #define N 2
- typedef char ElemType;
- #include"c2-3.h"
- #include"func2-2.cpp"
- #include"bo2-32.cpp"
- #include"func2-3.cpp" // 包括equal()、comp()、print()、print2()和print1()函数
- void difference(SLinkList space,int &S) // 算法2.17
- { // 依次输入集合A和B的元素,在一维数组space中建立表示集合(A-B)∪(B-A)
- // 的静态链表,S为其头指针。假设备用空间足够大,space[0].cur为备用空间的头指针
- int r,p,m,n,i,j,k;
- ElemType b;
- InitSpace(space); // 初始化备用空间
- S=Malloc(space); // 生成S的头结点
- r=S; // r指向S的当前最后结点
- printf("请输入集合A和B的元素个数m,n:");
- scanf("%d,%d%*c",&m,&n); // %*c吃掉回车符
- printf("请输入集合A的元素(共%d个):",m);
- for(j=1;j<=m;j++) // 建立集合A的链表
- {
- i=Malloc(space); // 分配结点
- scanf("%c",&space[i].data); // 输入A的元素值
- space[r].cur=i; // 插入到表尾
- r=i;
- }
- scanf("%*c"); // %*c吃掉回车符
- space[r].cur=0; // 尾结点的指针为空
- printf("请输入集合B的元素(共%d个):",n);
- for(j=1;j<=n;j++)
- { // 依次输入B的元素,若不在当前表中,则插入,否则删除
- scanf("%c",&b);
- p=S;
- k=space[S].cur; // k指向集合A中的第一个结点
- while(k!=space[r].cur&&space[k].data!=b)
- { // 在当前表中查找
- p=k;
- k=space[k].cur;
- }
- if(k==space[r].cur)
- { // 当前表中不存在该元素,插入在r所指结点之后,且r的位置不变
- i=Malloc(space);
- space[i].data=b;
- space[i].cur=space[r].cur;
- space[r].cur=i;
- }
- else // 该元素已在表中,删除之
- {
- space[p].cur=space[k].cur;
- Free(space,k);
- if(r==k)
- r=p; // 若删除的是尾元素,则需修改尾指针
- }
- }
- }
- void main()
- {
- int k;
- SLinkList s;
- difference(s,k);
- ListTraverse(s,k,print2);
- }
-
- // 第1个结点的位置在[0].cur中。成员cur的值为0,则到链表尾
- #include"c1.h"
- #define N 6 // 字符串长度
- typedef char ElemType[N];
- #include"c2-3.h"
- void main()
- {
- SLinkList s={{"",1},{"ZHAO",2},{"QIAN",3},{"SUN",4},{"LI",5},{"ZHOU",6},{"WU",7},{"ZHENG",8},{"WANG",0}}; // 教科书中图2.10(a)的状态
- int i;
- i=s[0].cur; // i指示第1个结点的位置
- while(i)
- { // 输出教科书中图2.10(a)的状态
- printf("%s ",s[i].data); // 输出链表的当前值
- i=s[i].cur; // 找到下一个
- }
- printf("/n");
- s[4].cur=9; // 按教科书中图2.10(b)修改(在"LI"之后插入"SHI")
- s[9].cur=5;
- strcpy(s[9].data,"SHI");
- s[6].cur=8; // 删除"ZHENG"
- i=s[0].cur; // i指示第1个结点的位置
- while(i)
- { // 输出教科书中图2.10(b)的状态
- printf("%s ",s[i].data); // 输出链表的当前值
- i=s[i].cur; // 找到下一个
- }
- printf("/n");
- }
-
- #include"c1.h"
- #define NAMELEN 8 // 姓名最大长度
- #define CLASSLEN 4 // 班级名最大长度
- struct stud // 记录的结构
- {
- char name[NAMELEN+1]; // 包括'/0'
- long num;
- char sex;
- int age;
- char Class[CLASSLEN+1]; // 包括'/0'
- int health;
- };
- typedef stud ElemType; // 链表结点元素类型为结构体
- #include"c2-2.h"
- #include"bo2-8.cpp" // 无头结点单链表的部分基本操作
- #include"func2-1.cpp" // 无头结点单链表的扩展操作
- char sta[3][9]={"健康 ","一般 ","神经衰弱"}; // 健康状况(3类)
- FILE *fp; // 全局变量
- void Print(stud e)
- { // 显示记录e的内容
- printf("%-8s %6ld",e.name,e.num);
- if(e.sex=='m')
- printf(" 男");
- else
- printf(" 女");
- printf("%5d %-4s",e.age,e.Class);
- printf("%9s/n",sta[e.health]);
- }
- void ReadIn(stud &e)
- { // 由键盘输入结点信息
- printf("请输入姓名(<=%d个字符): ",NAMELEN);
- scanf("%s",e.name);
- printf("请输入学号: ");
- scanf("%ld",&e.num);
- printf("请输入性别(m:男 f:女): ");
- scanf("%*c%c",&e.sex);
- printf("请输入年龄: ");
- scanf("%d",&e.age);
- printf("请输入班级(<=%d个字符): ",CLASSLEN);
- scanf("%s",e.Class);
- printf("请输入健康状况(0:%s 1:%s 2:%s):",sta[0],sta[1],sta[2]);
- scanf("%d",&e.health);
- }
- void WriteToFile(stud e)
- { // 将结点信息写入fp指定的文件
- fwrite(&e,sizeof(stud),1,fp);
- }
- Status ReadFromFile(stud &e)
- { // 由fp指定的文件读取结点信息到e
- int i;
- i=fread(&e,sizeof(stud),1,fp);
- if(i==1) // 读取文件成功
- return OK;
- else
- return ERROR;
- }
- int cmp(ElemType c1,ElemType c2)
- {
- return (int)(c1.num-c2.num);
- }
- void Modify(LinkList &L,ElemType e)
- { // 修改结点内容,并按学号将结点非降序插入链表L
- char s[80];
- Print(e); // 显示原内容
- printf("请输入待修改项的内容,不修改的项按回车键保持原值:/n");
- printf("请输入姓名(<=%d个字符): ",NAMELEN);
- gets(s);
- if(strlen(s))
- strcpy(e.name,s);
- printf("请输入学号: ");
- gets(s);
- if(strlen(s))
- e.num=atol(s);
- printf("请输入性别(m:男 f:女): ");
- gets(s);
- if(strlen(s))
- e.sex=s[0];
- printf("请输入年龄: ");
- gets(s);
- if(strlen(s))
- e.age=atoi(s);
- printf("请输入班级(<=%d个字符): ",CLASSLEN);
- gets(s);
- if(strlen(s))
- strcpy(e.Class,s);
- printf("请输入健康状况(0:%s 1:%s 2:%s):",sta[0],sta[1],sta[2]);
- gets(s);
- if(strlen(s))
- e.health=atoi(s); // 修改完毕
- InsertAscend(L,e,cmp); // 把q所指结点的内容按学号非降序插入L(func2-1.cpp)
- }
- #define N 4 // student记录的个数
- Status EqualNum(ElemType c1,ElemType c2)
- {
- if(c1.num==c2.num)
- return OK;
- else
- return ERROR;
- }
- Status EqualName(ElemType c1,ElemType c2)
- {
- if(strcmp(c1.name,c2.name))
- return ERROR;
- else
- return OK;
- }
- void main()
- { // 表的初始记录
- stud student[N]={{"王小林",790631,'m',18,"计91",0},{"陈红",790632,'f',20,"计91",1},
- {"刘建平",790633,'m',21,"计91",0},{"张立立",790634,'m',17,"计91",2}};
- int i,j,flag=1;
- char filename[13];
- ElemType e;
- LinkList T,p,q;
- InitList(T); // 初始化链表
- while(flag)
- {
- printf("1:将结构体数组student中的记录按学号非降序插入链表/n");
- printf("2:将文件中的记录按学号非降序插入链表/n");
- printf("3:键盘输入新记录,并将其按学号非降序插入链表/n");
- printf("4:删除链表中第一个有给定学号的记录/n");
- printf("5:删除链表中第一个有给定姓名的记录/n");
- printf("6:修改链表中第一个有给定学号的记录/n");
- printf("7:修改链表中第一个有给定姓名的记录/n");
- printf("8:查找链表中第一个有给定学号的记录/n");
- printf("9:查找链表中第一个有给定姓名的记录/n");
- printf("10:显示所有记录 11:将链表中的所有记录存入文件 12:结束/n");
- printf("请选择操作命令: ");
- scanf("%d",&i);
- switch(i)
- {
- case 1: for(j=0;j<N;j++)
- InsertAscend(T,student[j],cmp); // 在func2-1.cpp中
- break;
- case 2: printf("请输入文件名: ");
- scanf("%s",filename);
- if((fp=fopen(filename,"rb"))==NULL)
- printf("打开文件失败!/n");
- else
- {
- while(ReadFromFile(e))
- InsertAscend(T,e,cmp); // 在func2-1.cpp中
- fclose(fp);
- }
- break;
- case 3: ReadIn(e);
- InsertAscend(T,e,cmp); // 在func2-1.cpp中
- break;
- case 4: printf("请输入待删除记录的学号: ");
- scanf("%ld",&e.num);
- if(!DeleteElem(T,e,EqualNum)) // 在func2-1.cpp中
- printf("没有学号为%ld的记录/n",e.num);
- break;
- case 5: printf("请输入待删除记录的姓名: ");
- scanf("%*c%s",e.name); // %*c吃掉回车符
- if(!DeleteElem(T,e,EqualName)) // 在func2-1.cpp中
- printf("没有姓名为%s的记录/n",e.name);
- break;
- case 6: printf("请输入待修改记录的学号: ");
- scanf("%ld%*c",&e.num);
- if(!DeleteElem(T,e,EqualNum)) // 在链表中删除该结点,并由e返回(在func2-1.cpp)
- printf("没有学号为%ld的记录/n",e.num);
- else
- Modify(T,e); // 修改e并按学号插入链表T
- break;
- case 7: printf("请输入待修改记录的姓名: ");
- scanf("%*c%s%*c",e.name); // %*c吃掉回车符
- if(!DeleteElem(T,e,EqualName)) // 在func2-1.cpp中
- printf("没有姓名为%s的记录/n",e.name);
- else
- Modify(T,e);
- break;
- case 8: printf("请输入待查找记录的学号: ");
- scanf("%ld",&e.num);
- if(!(q=Point(T,e,EqualNum,p))) // 在func2-1.cpp中
- printf("没有学号为%ld的记录/n",e.num);
- else
- Print(q->data);
- break;
- case 9: printf("请输入待查找记录的姓名: ");
- scanf("%*c%s",e.name);
- if(!(q=Point(T,e,EqualName,p))) // 在func2-1.cpp中
- printf("没有姓名为%s的记录/n",e.name);
- else
- Print(q->data);
- break;
- case 10:printf(" 姓名 学号 性别 年龄 班级 健康状况/n");
- ListTraverse(T,Print);
- break;
- case 11:printf("请输入文件名: ");
- scanf("%s",filename);
- if((fp=fopen(filename,"wb"))==NULL)
- printf("打开文件失败!/n");
- else
- ListTraverse(T,WriteToFile);
- fclose(fp);
- break;
- case 12:flag=0;
- }
- }
- }
-
- #include"c1.h"
- typedef int ElemType;
- #include"c2-2.h"
- #include"bo2-2.cpp"
- #include"func2-3.cpp" // 包括equal()、comp()、print()、print2()和print1()函数
- void CreateList(LinkList &L,int n) // 算法2.11
- { // 逆位序(插在表头)输入n个元素的值,建立带表头结构的单链线性表L
- int i;
- LinkList p;
- L=(LinkList)malloc(sizeof(LNode));
- L->next=NULL; // 先建立一个带头结点的单链表
- printf("请输入%d个数据/n",n);
- for(i=n;i>0;--i)
- {
- p=(LinkList)malloc(sizeof(LNode)); // 生成新结点
- scanf("%d",&p->data); // 输入元素值
- p->next=L->next; // 插入到表头
- L->next=p;
- }
- }
- void CreateList2(LinkList &L,int n)
- { // 正位序(插在表尾)输入n个元素的值,建立带表头结构的单链线性表L
- int i;
- LinkList p,q;
- L=(LinkList)malloc(sizeof(LNode)); // 生成头结点
- L->next=NULL;
- q=L;
- printf("请输入%d个数据/n",n);
- for(i=1;i<=n;i++)
- {
- p=(LinkList)malloc(sizeof(LNode));
- scanf("%d",&p->data);
- q->next=p;
- q=q->next;
- }
- p->next=NULL;
- }
- void MergeList(LinkList La,LinkList &Lb,LinkList &Lc) // 算法2.12
- { // 已知单链线性表La和Lb的元素按值非递减排列。
- // 归并La和Lb得到新的单链线性表Lc,Lc的元素也按值非递减排列
- LinkList pa=La->next,pb=Lb->next,pc;
- Lc=pc=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; // 插入剩余段
- free(Lb); // 释放Lb的头结点
- Lb=NULL;
- }
- void main()
- {
- int n=5;
- LinkList La,Lb,Lc;
- printf("按非递减顺序, ");
- CreateList2(La,n); // 正位序输入n个元素的值
- printf("La="); // 输出链表La的内容
- ListTraverse(La,print);
- printf("按非递增顺序, ");
- CreateList(Lb,n); // 逆位序输入n个元素的值
- printf("Lb="); // 输出链表Lb的内容
- ListTraverse(Lb,print);
- MergeList(La,Lb,Lc); // 按非递减顺序归并La和Lb,得到新表Lc
- printf("Lc="); // 输出链表Lc的内容
- ListTraverse(Lc,print);
- }
-
- // *pa=*pb时,只将两者中之一插入Lc。此操作的结果和算法2.1相同
- #include"c1.h"
- typedef int ElemType;
- #include"c2-1.h"
- #include"bo2-1.cpp"
- #include"func2-3.cpp" // 包括equal()、comp()、print()、print2()和print1()函数
- void MergeList(SqList La,SqList Lb,SqList &Lc)
- { // 另一种合并线性表的方法(根据算法2.7下的要求修改算法2.7),La、Lb和Lc均为按递增排列的表
- ElemType *pa,*pa_last,*pb,*pb_last,*pc;
- pa=La.elem;
- pb=Lb.elem;
- Lc.listsize=La.length+Lb.length; // 此句与算法2.7不同
- pc=Lc.elem=(ElemType *)malloc(Lc.listsize*sizeof(ElemType));
- if(!Lc.elem)
- exit(OVERFLOW);
- pa_last=La.elem+La.length-1;
- pb_last=Lb.elem+Lb.length-1;
- while(pa<=pa_last&&pb<=pb_last) // 表La和表Lb均非空
- switch(comp(*pa,*pb)) // 此句与算法2.7不同
- {
- case 0: pb++;
- case -1: *pc++=*pa++;
- break;
- case 1: *pc++=*pb++;
- }
- while(pa<=pa_last) // 表La非空且表Lb空
- *pc++=*pa++;
- while(pb<=pb_last) // 表Lb非空且表La空
- *pc++=*pb++;
- Lc.length=pc-Lc.elem; // 加此句
- }
- void main()
- {
- SqList La,Lb,Lc;
- int j;
- InitList(La); // 创建空表La
- for(j=1;j<=5;j++) // 在表La中插入5个元素,依次为1、2、3、4、5
- ListInsert(La,j,j);
- printf("La= "); // 输出表La的内容
- ListTraverse(La,print1);
- InitList(Lb); // 创建空表Lb
- for(j=1;j<=5;j++) // 在表Lb中插入5个元素,依次为2、4、6、8、10
- ListInsert(Lb,j,2*j);
- printf("Lb= "); // 输出表Lb的内容
- ListTraverse(Lb,print1);
- MergeList(La,Lb,Lc); // 由按递增排列的表La、Lb得到按递增排列的表Lc
- printf("Lc= "); // 输出表Lc的内容
- ListTraverse(Lc,print1);
- }
-
- #include"c1.h"
- typedef int ElemType;
- #include"c2-1.h"
- #include"bo2-1.cpp"
- #include"func2-3.cpp" // 包括equal()、comp()、print()、print2()和print1()函数
- void MergeList(SqList La,SqList Lb,SqList &Lc) // 算法2.7
- { // 已知顺序线性表La和Lb的元素按值非递减排列。
- // 归并La和Lb得到新的顺序线性表Lc,Lc的元素也按值非递减排列
- ElemType *pa,*pa_last,*pb,*pb_last,*pc;
- pa=La.elem;
- pb=Lb.elem;
- Lc.listsize=Lc.length=La.length+Lb.length; // 不用InitList()创建空表Lc
- pc=Lc.elem=(ElemType *)malloc(Lc.listsize*sizeof(ElemType));
- if(!Lc.elem) // 存储分配失败
- exit(OVERFLOW);
- pa_last=La.elem+La.length-1;
- pb_last=Lb.elem+Lb.length-1;
- while(pa<=pa_last&&pb<=pb_last) // 表La和表Lb均非空
- { // 归并
- if(*pa<=*pb)
- *pc++=*pa++; // 将pa所指单元的值赋给pc所指单元后,pa和pc分别+1(指向下一个单元)
- else
- *pc++=*pb++; // 将pb所指单元的值赋给pc所指单元后,pa和pc分别+1(指向下一个单元)
- } // 以下两个while循环只会有一个被执行
- while(pa<=pa_last) // 表La非空且表Lb空
- *pc++=*pa++; // 插入La的剩余元素
- while(pb<=pb_last) // 表Lb非空且表La空
- *pc++=*pb++; // 插入Lb的剩余元素
- }
- void main()
- {
- SqList La,Lb,Lc;
- int j;
- InitList(La); // 创建空表La
- for(j=1;j<=5;j++) // 在表La中插入5个元素,依次为1、2、3、4、5
- ListInsert(La,j,j);
- printf("La= "); // 输出表La的内容
- ListTraverse(La,print1);
- InitList(Lb); // 创建空表Lb
- for(j=1;j<=5;j++) // 在表Lb中插入5个元素,依次为2、4、6、8、10
- ListInsert(Lb,j,2*j);
- printf("Lb= "); // 输出表Lb的内容
- ListTraverse(Lb,print1); // 由按非递减排列的表La、Lb得到按非递减排列的表Lc
- MergeList(La,Lb,Lc);
- printf("Lc= "); // 输出表Lc的内容
- ListTraverse(Lc,print1);
- }
-
- #include"c1.h"
- typedef int ElemType;
- #include"c2-1.h"
- #include"bo2-1.cpp"
- #include"func2-3.cpp" // 包括equal()、comp()、print()、print2()和print1()函数
- void MergeList(SqList La,SqList Lb,SqList &Lc) // 算法2.2
- { // 已知线性表La和Lb中的数据元素按值非递减排列。
- // 归并La和Lb得到新的线性表Lc,Lc的数据元素也按值非递减排列
- int i=1,j=1,k=0;
- int La_len,Lb_len;
- ElemType ai,bj;
- InitList(Lc); // 创建空表Lc
- La_len=ListLength(La);
- Lb_len=ListLength(Lb);
- while(i<=La_len&&j<=Lb_len) // 表La和表Lb均非空
- {
- GetElem(La,i,ai);
- GetElem(Lb,j,bj);
- if(ai<=bj)
- {
- ListInsert(Lc,++k,ai);
- ++i;
- }
- else
- {
- ListInsert(Lc,++k,bj);
- ++j;
- }
- } // 以下两个while循环只会有一个被执行
- while(i<=La_len) // 表La非空且表Lb空
- {
- GetElem(La,i++,ai);
- ListInsert(Lc,++k,ai);
- }
- while(j<=Lb_len) // 表Lb非空且表La空
- {
- GetElem(Lb,j++,bj);
- ListInsert(Lc,++k,bj);
- }
- }
- void main()
- {
- SqList La,Lb,Lc;
- int j,a[4]={3,5,8,11},b[7]={2,6,8,9,11,15,20};
- InitList(La); // 创建空表La
- for(j=1;j<=4;j++) // 在表La中插入4个元素
- ListInsert(La,j,a[j-1]);
- printf("La= "); // 输出表La的内容
- ListTraverse(La,print1);
- InitList(Lb); // 创建空表Lb
- for(j=1;j<=7;j++) // 在表Lb中插入7个元素
- ListInsert(Lb,j,b[j-1]);
- printf("Lb= "); // 输出表Lb的内容
- ListTraverse(Lb,print1);
- MergeList(La,Lb,Lc);
- printf("Lc= "); // 输出表Lc的内容
- ListTraverse(Lc,print1);
- }
-
- #include"c1.h"
- #include"c2-1.h" // 采用线性表的动态分配顺序存储结构
- #include"bo2-1.cpp" // 可以使用bo2-1.cpp中的基本操作
- #include"func2-3.cpp" // 包括equal()、comp()、print()、print2()和print1()函数
- typedef int ElemType;
- void Union(SqList &La,SqList Lb) // 算法2.1
- { // 将所有在线性表Lb中但不在La中的数据元素插入到La中
- ElemType e;
- int La_len,Lb_len;
- int i;
- La_len=ListLength(La); // 求线性表的长度
- Lb_len=ListLength(Lb);
- for(i=1;i<=Lb_len;i++)
- {
- GetElem(Lb,i,e); // 取Lb中第i个数据元素赋给e
- if(!LocateElem(La,e,equal)) // La中不存在和e相同的元素,则插入之
- ListInsert(La,++La_len,e);
- }
- }
- void main()
- {
- SqList La,Lb;
- int j;
- InitList(La); // 创建空表La。如不成功,则会退出程序的运行
- for(j=1;j<=5;j++) // 在表La中插入5个元素,依次为1、2、3、4、5
- ListInsert(La,j,j);
- printf("La= "); // 输出表La的内容
- ListTraverse(La,print1);
- InitList(Lb); // 创建空表Lb
- for(j=1;j<=5;j++) // 在表Lb中插入5个元素,依次为2、4、6、8、10
- ListInsert(Lb,j,2*j);
- printf("Lb= "); // 输出表Lb的内容
- ListTraverse(Lb,print1);
- Union(La,Lb); // 调用Union(),将Lb中满足条件的元素插入La
- printf("new La= "); // 输出新表La的内容
- ListTraverse(La,print1);
- }