顺序表A和B的合并与排序

来源:互联网 发布:知乎推广技巧 编辑:程序博客网 时间:2024/05/16 06:16

  用顺序表A和B表示的两个线性表,元素的个数分别是m和n, 若表中数据都是从小到大顺序排列的,且这(m+n)个数据中没有重复的。
  (1) 设计一个算法将此两个线性表合并成一个,仍是数据由小到大排列的线性表,存储到另一个顺序表C中。
  (2) 如果顺序表B的大小为(m+n)个单元,是否可不利用顺序表C而将合成的线性表存放于顺序表B中? 试设计算法。
  (3) 设顺序表A有m+n个元素,且前m个元素,后n个元素有序,设计一个算法,使得整个顺序表有序。
  解答:
  1)用ij分别扫描顺序表AB, 比较它们的当前元素,将较小者复制到顺序表C中,这一过程循环到其中一个顺序表扫描完毕为止。将另一个顺序表余下的元素全部复制到顺序表C中。算法如下:  

void meger1(SqList *&A, SqList *&B, SqList *&C){    int i=0,j=0,k=0; //i扫描A,j扫描B    while(i< A->length && j< B->length)    {        if (A->data[i] < B->data[j])        {            C->data[k] = A->data[i];            i++; k++;        }         else        {            C->data[k] = B->data[j];            j++; k++;        }    }    while(i< A->length){ //若A未扫描完,则将A剩余的元素加到CC->data[k] =A->data[i];        i++; k++;    }    while(j< B->length){ //若B未扫描完,则将B剩余的元素加到CC->data[k] = B->data[j];        j++; k++;    }    C->length=k;}

  本算法的时间复杂度为O(m+n), 空间复杂度为O(1)
2) 可以,将顺序表A中较小元素插入到B中即可,算法如下:

void meger2(SqList *&A, SqList *&B){    int i=0,j=0,k;    while(i< A->length){        if (A->data[i] > B->data[B->length-1]) //若A->data[i]大于B中所有元素        {             B->data[B->length]=A->data[i];  //将A->data[i]插入到B末尾            B->length++; i++;        }        else if(A->data[i] < B->data[j]){            for(k=B->length-1; k>=j; k--)                B->data[k+1] = B->data[k]; //将元素B->data[j]及之后的元素依次后移            B->data[j]=A->data[i]; //在位置j处插入            B->length++; //顺序表长度加1            i++; j++;        }        else j++;    }}

  本算法的时间复杂度O(mn), 空间复杂度为O(1)
3) 将顺序表A的后半部分插入到前半部分中,使整个表有序。算法如下:

void merge3(SqList *&A,int m,int n){    int i=0,j=m,k; //j扫描后半部分的有序表,并记录有序表前半部分的长度    ElemType tmp;    while(j< A->length && i<j){        if(A->data[j] > A->data[j-1]) //整个表有序,退出循环            break;        else if (A->data[j] < A->data[i]) //将A->data[i]插入到前半部分中        {            tmp=A->data[j];            for(k=j-1; k>=i; k--) //将A->data[i]及之后的元素后移                A->data[k+1] = A->data[k];            A->data[i]=tmp;  //将A->data[j]插入到i处            i++; j++;        }        else i++;    }}

  本算法的时间复杂度为O(mn), 空间复杂度为O(1)
完整代码如下:

#include <stdio.h>#include <malloc.h>#define MaxSize 50typedef int ElemType;typedef struct{    ElemType data[MaxSize];    int length;}SqList;void DispList(SqList *L){ //输出L中所有的元素    int i;    if(L->length==0) return;    for(i=0;i<L->length;i++)        printf("%d ",L->data[i]);    printf("\n");}void meger1(SqList *&A, SqList *&B, SqList *&C){    int i=0,j=0,k=0; //i扫描A,j扫描B    while(i< A->length && j< B->length)    {        if (A->data[i] < B->data[j])        {            C->data[k] = A->data[i];            i++; k++;        }         else        {            C->data[k] = B->data[j];            j++; k++;        }    }    while(i< A->length){ //若A未扫描完,则将A剩余的元素加到CC->data[k] =A->data[i];        i++; k++;    }    while(j< B->length){ //若B未扫描完,则将B剩余的元素加到CC->data[k] = B->data[j];        j++; k++;    }    C->length=k;}void meger2(SqList *&A, SqList *&B){    int i=0,j=0,k;    while(i< A->length){        if (A->data[i] > B->data[B->length-1]) //若A->data[i]大于B中所有元素        {             B->data[B->length]=A->data[i];  //将A->data[i]插入到B末尾            B->length++; i++;        }        else if(A->data[i] < B->data[j]){            for(k=B->length-1; k>=j; k--)                B->data[k+1] = B->data[k]; //将元素B->data[j]及之后的元素依次后移            B->data[j]=A->data[i]; //在位置j处插入            B->length++; //顺序表长度加1            i++; j++;        }        else j++;    }}void merge3(SqList *&A,int m,int n){    int i=0,j=m,k; //j扫描后半部分的有序表,并记录有序表前半部分的长度    ElemType tmp;    while(j< A->length && i<j){        if(A->data[j] > A->data[j-1]) //整个表有序,退出循环            break;        else if (A->data[j] < A->data[i]) //将A->data[i]插入到前半部分中        {            tmp=A->data[j];            for(k=j-1; k>=i; k--) //将A->data[i]及之后的元素后移                A->data[k+1] = A->data[k];            A->data[i]=tmp;  //将A->data[j]插入到i处            i++; j++;        }        else i++;    }}void main(){    SqList *A = (SqList*)malloc(sizeof(SqList));    A->length=0;    A->data[0]=3;    A->data[1]=7;    A->data[2]=15;    A->data[3]=18;    A->data[4]=26;    A->length=5;    SqList *B = (SqList*)malloc(sizeof(SqList));    B->length=0;    B->data[0]=4;    B->data[1]=11;    B->data[2]=20;    B->length=3;    SqList *C = (SqList*)malloc(sizeof(SqList));    C->length=0;    SqList *A2 = (SqList*)malloc(sizeof(SqList));    A2->length=0;    A2->data[0]=3;    A2->data[1]=7;    A2->data[2]=11;    A2->data[3]=20;    A2->data[4]=4;    A2->data[5]=8;    A2->data[6]=16;    A2->length=7;    DispList(A);    DispList(B);    //1)第一种方法合并    //meger1(A,B,C);    //DispList(C);    //2) 第二种方法合并    meger2(A,B);    DispList(B);    //3) 对A进行排序//  DispList(A2);//  merge3(A2,4,3);//  DispList(A2);    free(A);    free(B);    free(C);    free(A2);}

效果如下:

这里写图片描述
图(1) 将A和B合并

这里写图片描述
图(2) 对A进行排序

0 0