合并有序的顺序表

合并顺序表

问题描述: 将两个升(降)序的顺序表合成一个升(降)序的顺序表。(写下来以升序为例)

分析:

1.设有两个升序的顺序表s1,s2;合成一个顺序表s。

2.则顺序表s的第一个元素是最小的,也就是顺序表s1和s2两个顺序表中的最小值,这个最小值一定在s1或s2的第一个元素。

3.找到最小值,接下来s的第二个值是谁呢?是s1和s2构成的集合中,除了s中的第一个值的最小值。

4.用一个指针i指向s1的第一个元素,j指向s2的第一个元素,比较第s1中i指向的值和s2中j指向的值,将较小的值存入s,对应的指针加1。(如果对于形式化的描述看的不是很清晰,请看代码)

//顺序表类型定义
typedef struct{

    int data[1001];
    int length;
}SeqList; 

//这个函数是用来创建顺序表的
SeqList * InitSeqList(int n){

    SeqList *s = (SeqList *)malloc(sizeof(SeqList));
    s->length = n;
    for(int i=0;i<n;++i)
        scanf("%d",s->data+i);

    return s;
}

//按照上述分析的代码如下
SeqList * Merge1(SeqList *s1, SeqList *s2){
    //首先创建一个空的顺序表s
    SeqList *s = InitSeqList(0);

    int i = 0;//i用来遍历s1
    //因为每次要挑出最小的值,i指向s1没存的那一部分的第一个值
    int j = 0;//j用来遍历s2
    //j和i的用处一样
    int k = 0;//k用来在s中存储
    //每次往s->data[k]中存值

    while(i<s1->length && j<s2->length){

        if(s1->data[i] < s2->data[j])
            s->data[k++] = s1->data[i++];
        else
            s->data[k++] = s2->data[j++];
    }
    //因为是比较一次存一个值,最后有一个顺序表一定有剩余,补在后边即可
    while(i<s1->length){

        s->data[k++] = s1->data[i++];
    }
    while(j<s2->length){

        s->data[k++] = s2->data[j++];
    }
    s->length = k;
    return s;

}

对上述代码进行简化

上面的代码只是有两中操作: 
1.向s中存s1->data[i] 
2.向s中存s2->data[j]

那么,如果找到一个关系,可以用一个选择结构分别处理这两种情况,就可以减少代码量。

即:

if(条件A){
    s->data[k++] = s1->data[i++];
}
else
    s->data[k++] = s2->data[j++];

接下来只要找到条件A即可: 什么时候存s1呢? 
1.s2如果存完了,则存储s1即可 
2.在s1和s2都没存完的情况下,并且s1->data[i]<s2->data[j] 3.整合条件即可

SeqList * Merge2(SeqList *s1, SeqList *s2){

    SeqList *s = InitSeqList(0);

    int i = 0;//i用来遍历s1
    int j = 0;//j用来遍历s2
    int k = 0;//k用来在s中存储

    //注意这里的逻辑连接词是||;第一种方法的是&&
    while(i<s1->length || j<s2->length){
        //再循环条件中,有个前提就是s1和s2至少有一个没有存完
        if(j == s2->length || i<s1->length && s1->data[i]<s2->data[j])
        //||是个短路运算符,如果j==s2->length不成立,说明s2没有存完,则需要与s1比较
        //如果j==s2->length成立,则说明s2存完了,存储s1即可
            s->data[k++] = s1->data[i++];
        else
            s->data[k++] = s2->data[j++];
    } 
    s->length = k;

    return s;
}

最后提一句,如果是一个升序的一个降序的,怎么和成一个升序,或者一个降序的顺序表?

可以将其中一个先进行逆置操作哦(⊙o⊙)

猜你喜欢

转载自blog.csdn.net/qq2071114140/article/details/84332754