线性表的顺序表示和实现

概念: 线性表的顺序表示指的是用一组地址连续的存储单元依次存储线性表的数据元素。假设线性表的每个元素需占用l个存储单元,并以所占的第一个存储地址做为数据元素的存储位置。则线性表中第i+1个数据元素的存储位置 L O C ( a i + 1 ) LOC(a_{i+1}) LOC(ai+1) 和第i个数据元素的存储位置 L O C ( a i ) LOC(a_i) LOC(ai) 之间满足下列关系:
L O C ( a i + 1 ) LOC(a_{i+1}) LOC(ai+1) = L O C ( a i ) LOC(a_i) LOC(ai) + l
一般来说,线性表的第i个数据元素 a i a_i ai 的存储位置为
L O C ( a i ) LOC(a_i) LOC(ai) = L O C ( a 1 ) LOC(a_1) LOC(a1) + (i-1) × \times ×l;

线性表的顺序实现之创建线性表

#define LIST_INIT_SIZE 100     // 线性表存储空间的初始化分配量
typedef struct {
    int *element;
    int length;
    int listSize;
}List;

//构造一个空的线性表L
List* InitList(){

    List *L = (List *)malloc(sizeof(List));
    L->element = (int *)malloc(sizeof(int));
    if (!L->element) {
        return NULL;//存储分配失败
    }
    L->length = 0;                  //空表长度为0
    L->listSize = LIST_INIT_SIZE;   //初始化存储量
    
    return L; //创建完成
    
}

线性表的顺序实现之插入数据

int ListInsert(List *L,int i, int e){
//在顺序线性表L中第i个位置之前插入新的元素e
    //i的合法值为1<= i <= L->length
    
    if (i<1 || i > L->length + 1) {
        printf("i值不合法\n");
        return 0;
    }
    
    if (L->length*sizeof(int) >= L->listSize) {  //当前存储空间已满,增加分配
        int *newBase = (int *)realloc(L->element, L->listSize+sizeof(int));
        if (!newBase) {
            printf("存储分配失败");
            exit(OVERFLOW);
        }
        
        L->element = newBase;
        L->listSize += sizeof(int);
        
    }
    int *p,*q;
    q = &(L->element[i-1]);    //q为插入位置
    for (p=&(L->element[L->length-1]); p>=q; --p) {
        *(p+1) = *p; // 插入位置及之后的元素右移
        //这里主要是处理在线性表中间插入数据时进行的操作
    }
    
    *q = e;        //插入元素e
    ++L->length;   //表增长1
    
    return 1;  //插入成功
}

我们此时可以把线性表看作有一排正方形的箱子排列在一起,如果在这排箱子中插入一个箱子,那么在插入箱子后面的所有箱子都要往后移动一个箱子的位置。

线性表的顺序实现之删除数据

int ListDelete(List *L,int i){
    
    if (i<1||i>L->length) {
        printf("i值不合法");
        return 0;
    }
    
    int *p,*q;
    q = &(L->element[i-1]);
    
    for (p=q+1 ; p<&(L->element[L->length]); p++) {
        *(p-1) =*p;
        //删除线性表中间的数据时进行的操作
    }
    
    --L->length;

    return 1;//删除成功
}

我们此时可以把线性表看作有一排正方形的箱子排列在一起,如果在这排箱子中移除一个箱子,那么在插入箱子后面的所有箱子都要往前移动一个箱子的位置。

线性表的顺序实现之两个线性表的合并

  两个线性表LA和LB分别表示两个集合A和B(即线性表中的数据元素即为集合中的元素),现要求一个新的集合 A = A ⋃ B A= A\bigcup B A=AB
方法:扩大线性表LA,将存在于线性表LB而不存在于线性表LA中的数据元素插入到线性表LA中去。实现源码如下:

void ListUnion1(List *La,List *Lb){
    int lengthA = La->length;
    int lengthB = Lb->length;
    for (int i = 0; i<lengthB; i++) {
        
        int elementB = Lb->element[i];
        for (int j =0; j<lengthA; j++) {
            if (elementB == La->element[j]) {
                break;
            }else{
                if (j==lengthB-1) {//遍历完Lb都没有相同的就插入La
                    ListInsert(La, La->length+1, elementB);
                }
            }
            
        }
        
    }

}

通过代码分析可知该算法的时间复杂度为O(ListLength(LA) × \times ×ListLength(LB)).

  如果LA,LB中的元素都是按照升序排列,并且合并后的线性表也是按照升序排列。(合并后不能有相同的元素哦)
方法:新创建一个线性表LC,将LA,LB中的元素进行比较后按照升序插入LC。代码如下:

List* MergeList(List *La,List *Lb){

    List *Lc= InitList();
    int lengthA = La->length;
    int lengthB = Lb->length;
    int i,j,k;
    i=j=k=0;
    while ((i<lengthA)&&(j<lengthB)) {
        int elementA = La->element[i];
        int elementB = Lb->element[j];
        if (elementA<elementB) {
          
            ListInsert(Lc, ++k, elementA);
            ++i;
        }else if(elementA>elementB){
            ListInsert(Lc, ++k, elementB);
            ++j;
        
        }else{
            ListInsert(Lc, ++k, elementA);
            ++i;
            ++j;
        }
    }
    
    for (int i = 0; i<Lc->length; i++) {
        
        printf("Lc is %d\n",Lc->element[i]);
        
    }
    
    while (i<lengthA) {
        int elementA = La->element[i];
        ListInsert(Lc, ++k, elementA);
        ++i;
    };
    while (j<lengthB) {
        int elementB = Lb->element[j];
        printf("elementB %d\n\n",elementB);
        ListInsert(Lc, ++k, elementB);
        ++j;
    }
    
    free(La);
    free(Lb);
    return Lc;
}

线性表的顺序实现之线性表逆序

这个比较简单我这边主要利用了变量的交换进行的操作,具体代码如下:

void ReverseList(List *La){

    for (int i =0; i<La->length; i++) {
        int tempElement = La->element[i];
        if (i<=La->length-1-i) {
            La->element[i] = La->element[La->length-1-i];
            La->element[La->length-1-i] = tempElement;
        }
       
    }

}

运行结果我这里就不一一贴出来了,感兴趣的小伙伴们可以验证一下哦。

相关推荐
©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页