1,无序情况
利用两个线性表L1,L2分别表示两个集合A,B,现在要求用一个新的集合A来表示归并后的集合,也就是在A的基础上把B中与A不同的元素归并到A中,这样得到的A就是两个集合的归并。
思路:
1>B中的元素依次取出与A中的元素挨个比较,如果该元素与A中的元素均不等,则将该元素插入到线性表A的后边。
2>将B中的每一个元素都比较完且都已经按条件插入到A中,这样得到的A即时归并后的集合。
注意:线性表A申请的动态空间大小要求能承载归并后所有的元素。
遇到的问题:1>函数指针作为函数的参数这一块刚开始没有理解明白,对函数指针的概念理解不够透彻。
2>对于函数参数中什么时候需要引用什么时候不用理解不清晰。
以下为实验代码:
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#define OK 1
#define TRUE 1
#define ERROR 0
#define FALSE 0
#define OVERFLOW -2
#define INFEASIBLE -1
typedef int Status;
typedef Status ElemType;
typedef ElemType * List;
/* run this program using the console pauser or add your own getch, system("pause") or input loop */
Status InitList(List &L);
Status ListLength(List L);
Status ListInsert(List &L,ElemType i,ElemType e);
Status equal(ElemType e1,ElemType e2);
Status LocateElem(List L,ElemType e,Status (*equal)(ElemType,ElemType));
Status GetElem(List L,ElemType i,ElemType &e);
void uion(List &L1,List L2);
Status DestroyList(List &L);
int main(int argc, char *argv[]) {
List L1;
List L2;
Status i=0,s,u;
if(InitList(L1)==0){
printf("列表一动态内存空间申请失败;");
}
List a1=L1;
printf("请输入线性表L1待输入元素的个数:");
scanf("%d",&s);
if(s>10){
printf("输入个数超过申请空间的范围");
}else{
printf("请输入线性表1的元素:");
for(i=0;i<s;i++){
scanf("%d",(a1+i));
}
}
printf("\n");
if(InitList(L2)==0){
printf("列表二动态内存空间申请失败;");
}
List a2=L2;
printf("请输入线性表L1待输入元素的个数:");
scanf("%d",&u);
if(u>10){
printf("输入个数超过申请空间的范围");
}else{
printf("请输入线性表2的元素:");
for(i=0;i<u;i++){
scanf("%d",(a2+i));
}
}
printf("\n");
/********检验插入函数的功能是否实现************
Status a,b;
printf("输入待插入元的位置以及数值(试验先插入L1当中):");
scanf("%d",&a);
scanf("%d",&b);
ListInsert(L1,a,b);
printf("输出插入元素以后表L1的元素序列:");
for(i=0;i<ListLength(L1);i++){
printf(" %d",L1[i]);
}
*/
uion(L1,L2);
printf("请输出归并后L1的元素序列:");
for(i=0;i<ListLength(L1);i++){
printf(" %d ",L1[i]);
}
printf("\n");
if(DestroyList(L1)){
printf("线性表L1已经销毁;\n");
}
if(DestroyList(L2)){
printf("线性表L2已经销毁;\n");
}
return 0;
}
Status InitList(List &L){
L=(ElemType*)malloc(sizeof(ElemType)*12);
if(L==NULL){
return ERROR;
}else{
return OK;
}
}
Status ListLength(List L){ //返回列表的长度
Status m=0;
while(*L++){
m++;
}
return m;
}
Status ListInsert(List &L,ElemType i,ElemType e){ //在L的第i个元素前插入元素e
ElemType j;
for(j=ListLength(L);j>=i;--j){
*(L+j)=*(L+j-1);
}
*(L+i-1)=e;
}
Status equal(ElemType e1,ElemType e2){
if (e1==e2){
return 0;
}else{
return 2;
}
}
Status LocateElem(List L,ElemType e,Status (*equal)(ElemType,ElemType)){ //判断L1的表中是否有与元素e相同的元素
Status i=1;
while(i<=ListLength(L)&&(*equal)(L[i-1],e)){
i++;
}
if(i<=ListLength(L)){
return i;
}else{
return 0;
}
}
Status GetElem(List L,ElemType i,ElemType &e){ //用e返回函数中第i个元素的值
e=L[i-1];
return e;
}
void uion(List &L1,List L2){
Status L1_length=ListLength(L1);
Status L2_length=ListLength(L2);
Status i,e;
for(i=1;i<=L2_length;i++){
GetElem(L2,i,e); //L2中逐个取出元素
if(!LocateElem(L1,e,eAqual)){ //L2中的元素挨个与L1中的元素比较异同
ListInsert(L1,++L1_length,e); //不重复则插入到L1当中
}
}
}
Status DestroyList(List &L){
free(L);
L=NULL;
return OK;
}
运行结果:
2,有序情况
注意:要求进行归并的两个数列必须是有序的,本代码是按照课本写的非递减数列;
思路:新申请一个空间L3,将L1与L2中的元素依次取出进行比较,然后如果将数值较小的放入L3中,取走元素的列表继续取下一个元素进行比较,没有取出元素的序列不变,依次循环进行,最后直到L1或者L2中有一个序列的元素取完为止,对于还剩有元素的序列将剩下的元素归并的新列表L3当中。
遇到的问题:
1>malloc函数是没有初始化的,所以在创建的时候为了方便起见给每个新申请的空间均初始化为0;
2>以后写函数的时候不要依据数组的存放方式第一个是*(L+0)这样写,这样容易在调用的时候混乱,直接在写的时候就按照第一个是第一个这样的方式对数列操作,这样调用函数的时候也思路清晰不宜出错;
实验代码:
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <malloc.h>
#define OK 1
#define TRUE 1
#define ERROR 0
#define FALSE 0
#define OVERFLOW -2
#define INFEASIBLE -1
typedef int Status;
typedef Status ElemType;
typedef ElemType * List;
/* run this program using the console pauser or add your own getch, system("pause") or input loop */
Status InitList(List &L);
Status ListLength(List L);
Status ListInsert(List &L,ElemType i,ElemType e);
Status equal(ElemType e1,ElemType e2);
Status LocateElem(List L,ElemType e,Status (*equal)(ElemType,ElemType));
Status GetElem(List L,ElemType i,ElemType &e);
void uion(List &L1,List L2);
Status DestroyList(List &L);
void MergeList(List L1,List L2,List &L3);
int main(int argc, char *argv[]) {
List L1;
List L2;
Status i=0,s,u;
if(InitList(L1)==0){
printf("列表一动态内存空间申请失败;");
}
List a1=L1;
printf("请输入线性表L1待输入元素的个数:");
scanf("%d",&s);
if(s>10){
printf("输入个数超过申请空间的范围");
}else{
printf("请输入线性表1的元素:");
for(i=0;i<s;i++){
scanf("%d",(a1+i));
}
}
printf("\n");
if(InitList(L2)==0){
printf("列表二动态内存空间申请失败;");
}
List a2=L2;
printf("请输入线性表L2待输入元素的个数:");
scanf("%d",&u);
if(u>10){
printf("输入个数超过申请空间的范围");
}else{
printf("请输入线性表2的元素:");
for(i=0;i<u;i++){
scanf("%d",(a2+i));
}
}
printf("\n");
/********检验插入函数的功能是否实现************
Status a,b;
printf("输入待插入元的位置以及数值(试验先插入L1当中):");
scanf("%d",&a);
scanf("%d",&b);
ListInsert(L1,a,b);
printf("输出插入元素以后表L1的元素序列:");
for(i=0;i<ListLength(L1);i++){
printf(" %d",L1[i]);
}
*/
List L3;
if(InitList(L3)==0){ //新创建一个表用于存放从L1与L2中去取出元素
printf("列表三动态内存空间申请失败;");
}
MergeList(L1,L2,L3);
printf("有序归并后元素的序列:");
for(i=0;i<ListLength(L3);i++){
printf(" %d ",L3[i]);
}
printf("\n");
if(DestroyList(L1)){
printf("线性表L1已经销毁;\n");
}
if(DestroyList(L2)){
printf("线性表L2已经销毁;\n");
}
if(DestroyList(L3)){
printf("线性表L3已经销毁;\n");
}
return 0;
}
Status InitList(List &L){
L=(ElemType*)malloc(sizeof(ElemType)*12);
memset(L,0,sizeof(ElemType)*12);
if(L==NULL){
return ERROR;
}else{
return OK;
}
}
Status ListLength(List L){ //返回列表的长度
Status m=0;
while(*L++){
m++;
}
return m;
}
Status ListInsert(List &L,ElemType i,ElemType e){ //在L的第i个元素前插入元素e
ElemType j;
for(j=ListLength(L);j>=i;--j){
*(L+j)=*(L+j-1);
}
*(L+i-1)=e;
}
Status equal(ElemType e1,ElemType e2){
if (e1==e2){
return 0;
}else{
return 2;
}
}
Status LocateElem(List L,ElemType e,Status (*equal)(ElemType,ElemType)){ //判断L1的表中是否有与元素e相同的元素
Status i=1;
while(i<=ListLength(L)&&(*equal)(L[i-1],e)){
i++;
}
if(i<=ListLength(L)){
return i;
}else{
return 0;
}
}
Status GetElem(List L,ElemType i,ElemType &e){ //用e返回函数中第i个元素的值
e=L[i-1];
return e;
}
void MergeList(List L1,List L2,List &L3){
Status L1_length=ListLength(L1);
Status L2_length=ListLength(L2);
Status L3_length=0;
Status i1=1,i2=1,e1,e2,m;
while((i1<=L1_length)&&(i2<=L2_length)){
GetElem(L1,i1,e1);
GetElem(L2,i2,e2); //L2中逐个取出元素
if(e1<=e2){
ListInsert(L3,++L3_length,e1);
i1++;
}else{
ListInsert(L3,++L3_length,e2);
i2++;
}
}
if(i1<L1_length){
while(i1<=L1_length){
GetElem(L1,i1,e1);
ListInsert(L3,++L3_length,e1);
i1++;
}
}else if(i2<L2_length){
while(i2<=L2_length){
GetElem(L2,i2,e2);
ListInsert(L3,++L3_length,e2);
i2++;
}
}
}
Status DestroyList(List &L){
free(L);
L=NULL;
return OK;
}
运行结果: