シーケンシャルストレージ構造により、線形テーブルの挿入、削除、結合を実現

#include <stdio.h>
#include <stdlib.h>
#define ElemType int
#define OVERFLOW -1
#define OK 1
#define ERROR 0

typedef int Status;
#define LIST_INIT_SIZE 100		//线性表存储空间初始分配量
#define INCREMENT 10	//线性表存储空间的分配增量

typedef struct{
    
    
	ElemType *elem;		//存储空间基址
	int length;		//当前长度
	int listsize;	//当前分配的存储容量
}Sqlist;

//初始化线性表
Status InitSqList(Sqlist *List){
    
    
	(*List).elem=(ElemType *)malloc(sizeof(ElemType)*LIST_INIT_SIZE);
	if(!(*List).elem){
    
    
	//内存分配失败
		return OVERFLOW;
	}
	(*List).length=0;
	(*List).listsize=LIST_INIT_SIZE;
	return OK;
}

//向线性表中增加元素,需要提供元素的插入位置
//例如,参数i为3,则插入到List.elem[2]的位置
Status ListInsert_Sq(Sqlist *List,int i,ElemType e){
    
    
	//判断i是否合法
	if(i<1||i>(*List).length+1){
    
    
		return ERROR;
	}
	//判断是否需要再分配存储空间
	if((*List).length>=(*List).listsize){
    
    
		ElemType* newBase=(ElemType *)realloc((*List).elem, ((*List).listsize+LISTINCREMENT)*sizeof(ElemType));
		//判断分配存储空间是否成功
        if(!newBase){
    
    
            return OVERFLOW;
        }
        (*List).elem=newBase;
        (*List).listsize+=LISTINCREMENT;
     }
     ElemType *q,*p;
    q=&(List->elem[i-1]);
    p=&(List->elem[List->length-1]);
    for(;p>=q;p--){
    
    
        *(p+1)=(*p);
    }
    *q=e;
    List->length++;
    return OK;
}

//需要指出要删除元素所在位置,这里是删除第i个,即List->elem[i-1]
//并使用e返回所删除元素的值
Status ListDelete_Sq(Sqlist *List,int i,ElemType *e){
    
    
    //判断i是否合法
    if(i<1||i>List->length){
    
    
        return ERROR;
    }
    //找到被删除元素所在地址
    ElemType *p=&(List->elem[i-1]);
    e=p;
    //找到最后一个元素的地址
    ElemType *q=List->elem+List->length-1;
    while (p<=q) {
    
    
        *(p)=*(p+1);
        p++;
    }
    List->length--;
    return OK;
}

//打印线性表中的元素
void Print_Sq(Sqlist List){
    
    
    ElemType *p,*q;
    p=List.elem;
    q=List.elem+List.length-1;
    while (p<=q) {
    
    
        printf("%d\n",*p);
        p++;
    }
}

//求并集
//这里所求结果为从小到大排列,要求La,Lb中的元素按照从小到大排序,先排好
Status Union(Sqlist La,Sqlist Lb,Sqlist *Lc){
    
    
    //初始化Lc
    Lc->elem=(ElemType *)malloc(sizeof(ElemType)*(La.length+Lb.length));
    if(!Lc->elem){
    
    
         exit(OVERFLOW);
    }
    Lc->listsize=La.length+Lb.length;
    //定义3个指针分别指向La,Lb,Lc的基地址
    ElemType *pa,*pb,*pc;
    pa=La.elem; pb=Lb.elem; pc=Lc->elem;
    
    //找到La,Lb最后一个元素的地址
    ElemType *pa_last=La.elem+La.length-1;
    ElemType *pb_last=Lb.elem+Lb.length-1;
    
    //循环判断大小,插入到Lc中;
    while (pa<=pa_last&&pb<=pb_last) {
    
    
        if(*pa<=*pb){
    
    
            *pc=*pa;
            pc++;
            pa++;
        }else{
    
    
            *pc=*pb;
            pc++;
            pb++;
        }
        Lc->length++;
    }
    while (pa<=pa_last) {
    
    
        *pc++=*pa++;
        Lc->length++;
    }
    while (pb<=pb_last) {
    
    
        *pc++=*pb++;
        Lc->length++;
    }
    return OK;
}


int main() {
    
    
    Sqlist La;
    Sqlist Lb;
    Sqlist Lc;
    InitSqList(&La);
    InitSqList(&Lb);
    for(int i=0;i<10;i++){
    
    
        ListInsert_Sq(&La, (i+1), i);
        ListInsert_Sq(&Lb, (i+1), i+3);
    }
    Print_Sq(La);
    Print_Sq(Lb);
    ElemType *e = NULL;
    ListDelete_Sq(&La, 3, e);
    printf("%d",*e);
    Print_Sq(La);
    Union(La, Lb, &Lc);
    Print_Sq(Lc);
    return 0;
}

ポイント

  • 挿入と削除の両方の操作には、要素の場所が必要です。つまり、指定された場所が毎回有効かどうかを判断する必要があります
    • 挿入:1 <= i <= List.length + 1;挿入は最後の位置、つまりList.elem [length]に挿入できます
    • 削除:1 <= i <List.length;
  • メモリ空間を割り当てる必要があるたびに、割り当てが成功したかどうかを判断する必要があります
  • 挿入するとき、現在のリニアテーブルの長さが現在割り当てられているストレージ容量を超えているかどうか、つまりList.length> = List.listsizeがあるかどうかを判断する必要があります。ある場合は、メモリを再割り当てする必要があります。
  • 挿入でも削除でも、位置を移動する必要があるため、線形テーブルの最後の要素の位置を見つける必要があります。

おすすめ

転載: blog.csdn.net/qq_45465526/article/details/103828225