【数据结构】归并 非降序的顺序表

【数据结构】归并 非降序的顺序表和链表

思想

时间复杂度(O(LA.length+LB.length))

  • 两顺序表进行每个元素的比较,如果比较小的就先插入进新的数组,若一个提前遍历完另一个就直接插入进新数组,所以走完过后就是两数组的长度相加。
  • 新数组初始化:2.2:顺序表不用声明两数组的长度和,直接初始化然后每一个在后面插入就行 2.7:第二种是提前建立一个两数组长度和的空间,然后用指针插入,全程没用SqList.cpp的内容。
  • 判断条件:首先考虑都没遍历完,然后考虑单个遍历完。

代码

MergeSqList.h 头文件

/*==================
 * 归并非降序顺序表和链表
 *
 * 包含算法: 2.2、2.7
 ===================*/

#ifndef MERGESQLIST_H
#define MERGESQLIST_H

#include <stdio.h>
#include <stdlib.h>
#include "SqList.h"        //**▲02 线性表**//


/*
 * ████████ 算法2.2 ████████
 *
 * 非递顺序表归并:C=A+B
 *
 * 归并顺序表La和Lb,生成新的顺序表Lc。
 * 其中,La、Lb、Lc均为非递减序列。
 */
void MergeSqList_1(SqList La, SqList Lb, SqList* Lc);

/*
 * ████████ 算法2.7 ████████
 *
 * 非递减顺序表归并:C=A+B
 *
 * 归并顺序表La和Lb,生成新的顺序表Lc。
 * 其中,La、Lb、Lc均为非递减序列。
 */
void MergeSqList_2(SqList La, SqList Lb, SqList* Lc);

#endif

MergeSqList.cpp 算法函数

/*==================
 * 归并非降序顺序表
 *
 * 包含算法: 2.2、2.7
 ===================*/

#include "MergeSqList.h"    //**▲02 线性表**//


/*
 * ████████ 算法2.2 ████████
 *
 * 非递减顺序表归并:C=A+B
 *
 * 归并顺序表La和Lb,生成新的顺序表Lc。
 * 其中,La、Lb、Lc均为非递减序列。
 */
void MergeSqList_1(SqList La, SqList Lb, SqList* Lc) {
    int La_len, Lb_len;
    int i, j, k;
    ElemType ai, bj;
    
    i = j = 1;
    k = 0;
    
    // 初始化Lc
    InitList(Lc);
    
    // 获取La、Lb的长度
    La_len = ListLength(La);
    Lb_len = ListLength(Lb);
    
    // 如果La及Lb均未遍历完
    while(i <= La_len && j <= Lb_len) {
        GetElem(La, i, &ai);
        GetElem(Lb, j, &bj);
        
        // 比较遍历到的元素,先将比较小的元素加入顺序表Lc
        if(ai <= bj) {
            ListInsert(Lc, ++k, ai);
            i++;
        } else {
            ListInsert(Lc, ++k, bj);
            j++;
        }
    }
    
    // 如果Lb已遍历完,但La还未遍历完,将La中剩余元素加入Lc
    while(i <= La_len) {
        GetElem(La, i++, &ai);
        ListInsert(Lc, ++k, ai);
    }
    
    // 如果La已遍历完,但Lb还未遍历完,将Lb中剩余元素加入Lc
    while(j <= Lb_len) {
        GetElem(Lb, j++, &bj);
        ListInsert(Lc, ++k, bj);
    }
}

/*
 * ████████ 算法2.7 ████████
 *
 * 非递减顺序表归并:C=A+B
 *
 * 归并顺序表La和Lb,生成新的顺序表Lc。
 * 其中,La、Lb、Lc均为非递减序列。
 */
void MergeSqList_2(SqList La, SqList Lb, SqList* Lc) {
    ElemType* pa, * pb, * pc;
    ElemType* pa_last, * pb_last;
    
    pa = La.elem;                        // 指向La第一个元素
    pb = Lb.elem;                        // 指向Lb第一个元素
    
    // 没有使用InitList创建Lc
    (*Lc).listsize = (*Lc).length = La.length + Lb.length;
    pc = (*Lc).elem = (ElemType*) malloc((*Lc).listsize * sizeof(ElemType));
    if(pc == NULL) {
        exit(OVERFLOW);
    }
    
    pa_last = La.elem + La.length - 1;    // 指向La最后一个元素
    pb_last = Lb.elem + Lb.length - 1;    // 指向Lb最后一个元素
    
    // 如果La及Lb均未遍历完
    while(pa <= pa_last && pb <= pb_last) {
        if(*pa <= *pb) {
            *pc++ = *pa++;
        } else {
            *pc++ = *pb++;
        }
    }
    
    // 如果Lb已遍历完,但La还未遍历完,将La中剩余元素加入Lc
    while(pa <= pa_last) {
        *pc++ = *pa++;
    }
    
    // 如果La已遍历完,但Lb还未遍历完,将Lb中剩余元素加入Lc
    while(pb <= pb_last) {
        *pc++ = *pb++;
    }
}

MergeSqList-main.cpp 主函数

#include <stdio.h>
#include "SqList.h"
#include "MergeSqList.h"                //**▲02 线性表**//

// 测试函数,打印元素
void PrintElem(ElemType e) {
    printf("%d ", e);
}


int main(int argc, char** argv) {
    ElemType a[4] = {3, 5, 8, 11};
    ElemType b[7] = {2, 6, 8, 9, 11, 15, 20};
    
    SqList La, Lb, Lc1, Lc2;
    int i;
    
    // 初始化La
    InitList(&La);
    for(i = 1; i <= 4; i++) {
        ListInsert(&La, i, a[i - 1]);
    }
    
    // 初始化Lb
    InitList(&Lb);
    for(i = 1; i <= 7; i++) {
        ListInsert(&Lb, i, b[i - 1]);
    }
    
    // 输出La
    printf("La = ");
    ListTraverse(La, PrintElem);
    
    // 输出Lb
    printf("Lb = ");
    ListTraverse(Lb, PrintElem);
    
    // 归并顺序表La和Lb,算法2.2
    MergeSqList_1(La, Lb, &Lc1);
    printf("归并La和Lb为Lc1 = ");
    ListTraverse(Lc1, PrintElem);
    
    // 归并顺序表La和Lb,算法2.7
    MergeSqList_2(La, Lb, &Lc2);
    printf("归并La和Lb为Lc2 = ");
    ListTraverse(Lc2, PrintElem);
    
    return 0;
}
原文地址:https://www.cnblogs.com/SiriusZHT/p/14310786.html