数据结构C语言线性表的顺序存储实现

原理是申请一段连续的内存空间,对这段内存空间进行相关操作实现基本的功能,大致实现了数据结构C语言版第二章顺序线性表的所有功能和算法,代码如下

#include"stdio.h"
#include"stdlib.h"
#define OVERFLOW 0
#define OK  1
#define LIST_INIT_SIZE  20
#define LISTINCREMENY  3
#define TRUE 1
#define FALSE 0

/*
结构体的定义如下,在该结构体中,有三个属性
指针变量elem用来存储数据,为一片连续空间的开始地址
length为当前长度,也就是存储元素的个数
LIST_INIT_SIZE为初始化申请的长度,也就是
该线性表开始时能存储的最大容量
*/
typedef int Status;
typedef struct{
    int *elem;//连续空间基地址,存储数据
    int length;//记录长度
    int listsize;//记录初始化线性表大小
    int exist;//判断符号表状态,申请成功赋值为1
}Sqlist;//将该结构体定义为Sqlist


//定义全局变量listsizeChange,记录线性表大小变化过程,开始值为初始化大小
int LISTSIZE_CHANGE = LIST_INIT_SIZE;
/*
线性表初始化函数,申请一片连续的空间存储数据
初始化线性表大小和当前容量
*/
int InitList(Sqlist *L){
    (*L).elem = (int *)malloc(LIST_INIT_SIZE * sizeof(int));//动态申请五个Int型大小的元素,用来存储数据,开始地址赋值给*L.elem
    if(!(*L).elem){//申请失败则返回FALSE
        return FALSE;
    }
    (*L).length = 0;//初始化时没有存储任何元素,线性表的长度为0
    (*L).listsize = LIST_INIT_SIZE;//申请的最大容量为当前长度
    (*L).exist = 1;
    return TRUE;
}

/*
销毁线性表,释放所申请的地址空间
*/
int DestroyList(Sqlist *L){
    free((*L).elem);//释放所申请的固定大小的内存空间
    (*L).elem = NULL;
    (*L).length = 0;
    (*L).listsize = 0;
    return 0;
}


/*
在结构体中插入数据,参数有结构体名,下标,插入元素
下标从0开始
版本一: 有限插入,线性表初始容量和可扩展容量都已经限定,不能超过给定的容量
*/

int InsertLIst(Sqlist *L, int i, int e){
    if((*L).exist == 1 && i >= 0 && i < LISTINCREMENY + LIST_INIT_SIZE){//当前大小空间等于全局变量大小,下标取值符合范围
        int *p, *q;//申请两个指针变量
        int *newbase;

    //新地址的开辟,只开辟一次, 当当前容量比最大容量大的时候开始开辟
    if((*L).length >= (*L).listsize){//当赋值下标超过了初始化分配的内存大小为,进行内存的扩张
        newbase = (int *)realloc((*L).elem, (LISTINCREMENY + LIST_INIT_SIZE)*sizeof(int));//重新分配内存,参数一为旧内存内容,参数而为新内存大小
        if(!newbase){
            printf("内存扩张失败");
            return FALSE;
        }
        (*L).elem = newbase;//将新分配的地址赋值给elem
        (*L).listsize = LISTINCREMENY + LIST_INIT_SIZE;
    }
    //插入算法
    q = (*L).elem + i;//q为要插入的地址位置,(*L).elem为初始地址加上地址偏移位数i就为要插入的初始地址
    //插入的算法为,把插入前的位置不变,当前位置和后面位置依次加一后移
    for(p = (*L).elem + (*L).length; p >= q; p --){//p为尾地址,将尾地址内存中数据后移一位
        *(p + 1) = *p;
    }
    *q = e;//将要插入的内存进行赋值
    (*L).length ++;
    return 1;
    }
    else{
            printf("下标越界\n");
        return FALSE;
    }
}

//线性表的遍历,打印输出每一个元素
int TraverseList(Sqlist *L){
    int *begin;
    begin = (*L).elem;
    for(begin = (*L).elem; begin <(*L).elem + (*L).length; begin ++){
        printf("%d\n", *begin);

    }
    return 0;
}

//将线性表置为空表,空表的条件就是长度为0
int ClearList(Sqlist *L){
    (*L).length = 0;
    return TRUE;
}

//判断是否为空表,如果为空返回true,否则返回false
int IsemptyList(Sqlist *L){
    if((*L).length == 0){
        return TRUE;
    }
    else{
        return FALSE;
    }
}

//获取线性表元素的个数,返回元素个数
int ListLength(Sqlist *L){
    return (*L).length;
}

//获取指定下标位置的元素
int GetElem(Sqlist *L, int i){
    if(i >=0 && i < (*L).length){
        return *((*L).elem + i);//返回特定内存位置的地址
    }
    return FALSE;


}

//返回第一个满足与元素e相等的下标,不存在则返回-1
int LocateElem(Sqlist *L, int e){
    int i = 0;
    int flag = 0;
    int *p;

    for(p = (*L).elem; p < (*L).elem + (*L).length; p ++){
        if(*p == e){
            flag ++;
            break;
        }
        i ++;
    }
    if(flag != 0){
        return i;
    }
    return -1;
}

//获取前驱元素
int PriorElem(Sqlist *L, int cur){
    int locate = LocateElem(L, cur);

    if(locate > 0 && locate < (*L).length){
        return *((*L).elem + locate - 1);
    }
    else{
        return -1;
    }

   // return locate;
}

//获取后继元素
int NextElem(Sqlist *L, int cur){
    int locate = LocateElem(L, cur);
    if(locate >= 0 && locate < (*L).length - 1){
        return *((*L).elem + locate + 1);
    }
    else{
        return -1;
    }
}

//删除指定下标位置的元素
int DeleteList(Sqlist *L, int i){
    int *p, *q;//p为要删除位置的地址,q为地址尾部
    for(p = (*L).elem + i; p < (*L).elem + (*L).length; p ++){
        *p = *(p + 1);
    }
    (*L).length --;
    return 1;
}

//对两个线性表进行集合操作,A = A并B,对两个集合进行并,操作,最后结果赋值给A
void UnionList(Sqlist *La, Sqlist *Lb){
    int LengthA = ListLength(La);
    int LengthB = ListLength(Lb);
    int i = 0;
    for(i = 0; i < LengthB; i ++){

        if(LocateElem(La, (GetElem(Lb, i))) == -1){//如果该元素在La中不存在

            InsertLIst(La, LengthA, GetElem(Lb, i));
            LengthA ++;



        }
    }
}

//对两个有序线性表按照输出重新加入到一个新的线性表中 L = LA 并 LB
void MergeList(Sqlist *L, Sqlist *La, Sqlist *Lb){
    //(*L).length = (*La).length + (*Lb).length;
    int LengthA = ListLength(La);
    int LengthB = ListLength(Lb);
    int i = 0;
    int j = 0;
    int k = 0;
    while((i < LengthA) && (j < LengthB)){
        if(GetElem(La, i) <= GetElem(Lb, j)){
            InsertLIst(L, k, GetElem(La, i));
            k ++;
            i ++;
        }
        else{
            InsertLIst(L, k, GetElem(Lb, j));
            k ++;
            j ++;
        }
    }
    while(i < LengthA){
        InsertLIst(L, k, GetElem(La, i));
        i ++;
    }
    while(j < LengthB){
        InsertLIst(L, k, GetElem(Lb, j));
        j ++;
    }

}



int main(){

    Sqlist L;//定义一个结构体L

    InitList(&L);//将初始化的结构体进行初始化,参数为该结构体的基地址
    Sqlist Lb;
    InitList(&Lb);
    InsertLIst(&Lb, 0, 1);
    InsertLIst(&Lb, 1, 11);
    InsertLIst(&Lb, 2, 22);
    Sqlist Lc;
    InitList(&Lc);



    InsertLIst(&L, 0, 1);
    InsertLIst(&L, 1, 2);
    InsertLIst(&L, 2, 3);
    InsertLIst(&L, 3, 4);
    InsertLIst(&L, 4, 5);
    InsertLIst(&L, 5, 6);
    InsertLIst(&L, 6, 7);
    InsertLIst(&L, 7, 8);
    MergeList(&Lc, &L, &Lb);

   // DeleteList(&L, 5);
    //UnionList(&L, &Lb);

   // printf("%d\n", Lc.length);
    TraverseList(&Lc);





    return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值