顺序表的应用示例

不羁岁月 提交于 2020-03-08 18:47:26

学习完最基本的线性表操作,我们开始学习运用这些强大的操作。一开始,大家可能很不习惯使用这些操作,但还是那句话,熟能生巧。只要你肯下功夫,什么都是手到擒来,代码都能变成金块。

我们今天来讲一下这道例题:

假设有两个集合A和B(元素都按非递减有序排列),分别用两个线性表La和Lb表示。利用线性表的基本运算设计一个算法求一个新的集合C,将两个集合的并集放在线性表Lc中,Lc仍按非递减有序排列。

大家有什么奇思妙想?先自己想一想,写一写,画一画。

 

想好了吗?下面贴我的代码:

SqList* UnionList(SqList La,SqList Lb,SqList* Lc){
    //函数的返回值是一个指向SqList结构体类型的指针。
    //形式参数包括两个待合并的有序顺序表La和Lb和一个指向未初始化的顺序表的指针Lc,该顺序表用于存放合并后的顺序表。
    int i=1,j=1,k=0;
    //i和j分别表示顺序表La和Lb中元素的逻辑位置。
    //k用来表实顺序表Lc中元素的逻辑位置。
    Lc=InitList(Lc);//初始化顺序表Lc。
    int ai,bj;//分别用来带出La和Lb顺序表中找到的元素。
    while(i<=ListLength(&La)&&j<=ListLength(&Lb)){
        //当i尚小于等于顺序表La的长度且j尚小于等于顺序表Lb的长度时,即两个顺序表都没有遍历完成时,持续循环。
        GetElem(&La,i,&ai);//取出顺序表La中第i个位置的元素,存放在变量ai中。
        GetElem(&Lb,j,&bj);//取出顺序表Lb中第j个位置的元素,存放在变量bj中。
        if(ai<bj){//如果La中此刻的元素小于Lb中此刻的元素
            ListInsert(Lc,++k,ai);//往顺序表Lc中插入较小的那个。
            i++;//元素下标往前移动一位。
        }
        else if(ai==bj){//如果此刻两个元素相等
            ListInsert(Lc,++k,ai);//往Lc中插入元素值。
            i++;
            j++;//两个顺序表中的元素同时向前移动一位。
        }
        else{//原理同第一个if语句。
            ListInsert(Lc,++k,bj);
            j++;
        }
    }
    //循环结束,两个线性表一定至少有一个遍历已经完成。
    while(i<=ListLength(&La)){//如果La表未遍历完,执行此循环,否则不执行,进入下一循环。
        GetElem(&La,i++,&ai);//取出La中的元素
        ListInsert(Lc,++k,ai);//将取出的元素插入Lc中。
    }
    while(j<=ListLength(&Lb)){//原理同上。
        GetElem(&Lb,j++,&bj);
        ListInsert(Lc,++k,bj);
    }
    return Lc;//返回指向已经合并好的顺序表的指针。
}

虽然我写了很详细的注释,但我还是觉得应该进一步讲解才能讲得更透彻。

比如,La是这样一个有序集合:{1,2,3,4,5,6,7,8,9,10},共计10个元素。Lb是:{1,2,4,8,16,32,64},共计7个元素。想要实现它们的并集仍然是一个有序集合,我们应该这样做:各自拿出两个顺序表的第一个元素

比较一下大小,发现元素大小相等,于是把1存入Lc中之后,i和j同时往前移动一位:

这时两个顺序表各自拿出第二个元素:

比较大小,发现元素仍然相等,把2存入Lc后,i和j同时再往前移动一位:

这时,两个顺序表各自拿出第三个元素:

比较大小,发现3比4小,于是把3存入Lc中,i往前移动一个位置,j不动:

这时,拿La的第四个元素和Lb的第三个元素比较大小:

此处省略一万字......

当La遍历结束时:

Lb指向元素16。跳出循环,进入下一个while循环,把所有Lb中剩余的元素取出来插入到Lc的末尾,求并集的过程就算完成了。

我们来用一个完整的程序测试一下:

#include<stdio.h>
#include<stdlib.h>
#include<stdbool.h>
#define MaxSize 50
typedef int ElemType;
typedef struct{
    ElemType data[MaxSize];
    int length;
}SqList;

SqList* InitList(SqList* L){
    L=(SqList*)malloc(sizeof(SqList));
    L->length=0;
    return L;
}
void DestroyList(SqList* L){
    free(L);
}
bool ListEmpty(SqList* L){
    return(L->length==0);
}
int ListLength(SqList* L){
    return(L->length);
}
void DispList(SqList* L){
    for(int i=0;i<L->length;i++)
        printf("%d\n",L->data[i]);
}
bool GetElem(SqList* L,int i,ElemType *e){
    if(i<1||i>L->length)return false;
    *e=L->data[i-1];
    return true;
}
int LocateElem(SqList* L,ElemType e){
    int i=0;
    while(i<L->length&&L->data[i]!=e)
        i++;
    if(i>=L->length)return 0;
    else return i+1;
}
bool ListInsert(SqList* L,int i,ElemType e){
    int j;
    if(i<1||i>L->length+1)return false;
    i--;
    for(j=L->length;j>i;j--)
        L->data[j]=L->data[j-1];
    L->data[i]=e;
    L->length++;
    return true;
}
bool ListDelete(SqList* L,int i,ElemType* e){
    int j;
    if(i<1||i>L->length)return false;
    i--;
    *e=L->data[i];
    for(j=i;j<L->length-1;j++)
        L->data[j]=L->data[j+1];
    L->length--;
    return true;
}

SqList* CreateList(SqList* L,ElemType a[],int n){
    int i=0,k=0;
    L = (SqList*)malloc(sizeof(SqList));
    while(i < n){
        L->data[i]=a[i];
        i++;
        k++;
    }
    L->length=k;
    return L;
}
SqList* UnionList(SqList La,SqList Lb,SqList* Lc){
    int i=1,j=1,k=0;
    Lc=InitList(Lc);
    int ai,bj;
    while(i<=ListLength(&La)&&j<=ListLength(&Lb)){
        GetElem(&La,i,&ai);
        GetElem(&Lb,j,&bj);
        if(ai<bj){
            ListInsert(Lc,++k,ai);
            i++;
        }
        else if(ai==bj){
            ListInsert(Lc,++k,ai);
            i++;
            j++;
        }
        else{
            ListInsert(Lc,++k,bj);
            j++;
        }
    }
    while(i<=ListLength(&La)){
        GetElem(&La,i++,&ai);
        ListInsert(Lc,++k,ai);
    }
    while(j<=ListLength(&Lb)){
        GetElem(&Lb,j++,&bj);
        ListInsert(Lc,++k,bj);
    }
    return Lc;
}

int main(int argc, char const *argv[])
{
    SqList *La,*Lb,*Lc;
    int a[10]={1,2,3,4,5,6,7,8,9,10};
    int b[7]={1,2,4,8,16,32,64};
    La=CreateList(La,a,10);
    Lb=CreateList(Lb,b,7);
    Lc=UnionList(*La,*Lb,Lc);
    DispList(Lc);
    return 0;
}

运行结果如下:

没有一个元素落下,没有任何两个元素重复,证明我们的试验成功了。

你还有什么更好的方法吗?欢迎留言交流!

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!