数据结构之顺序表

顺序表:逻辑上是连续存储的,在物理空间也是连续存储的,读取某个位置的元素O(1),在某个位置插入或删除O(n),头插或尾插或头删或尾删是O(1)

1、定长顺序表

结构:

#define SIZE 10

typedef int ElemType;
typedef struct SqList
{
    ElemType data[SIZE];
    int length;
}SqList,*SqListPtr;

初始化:

void Init_SqList(SqListPtr sqlist)
{
    if(sqlist == NULL)
        exit(0);
    sqlist->length = 0;
}

功能:删除(头删、尾插、按位删),清空,销毁,查找(按位查找,按条件查找),输出打印

 注意:

1、顺序表中按位插入数据时,需要判空、判满、判位置;按位删除时,需要判空、判位置;

2、头插和尾插不同,尾插时若直接调用按位插入的函数,相当于直接默认sqlist != NULL,但是我们是不确定他是否为空,故此,需要先判断sqlist是否为空,在调用按位插入的函数;

//判顺序表是否满
static int Is_Full_SqList(SqListPtr sqlist)
{
    if(sqlist->length == SIZE)
        return true;
    return false;
//插入(按位插入)
int InsertSqList_Pos(SqListPtr sqlist,ElemType val,int pos)
{
    if(NULL == sqlist)
        exit(0);
    if(Is_Full_SqList(sqlist))//判满
        return false;
    if(pos < 0 || pos > sqlist->length)//判位置是否合理
        return false;

    int i = sqlist->length;
    while(i > pos)
    {
        sqlist->data[i] = sqlist->data[i-1];
        i--;
    }
    sqlist->data[i] = val;
    sqlist->length++;
    return true;
}
//头插
int InsertSqList_Head(SqListPtr sqlist,ElemType val)
{
    return InsertSqList_Pos(sqlist,val,0);
}
//尾插
int InsertSqList_Tail(SqListPtr sqlist,ElemType val)
{
    if(sqlist == NULL)
        exit(0);
    return InsertSqList_Pos(sqlist,val,sqlist->length);
}

//按位删除
int DeleteSqList_Pos(SqListPtr sqlist,int pos)
{
    if(NULL == sqlist)
        exit(0);
    if(pos < 0 || pos >= sqlist->length)
        return false;
    int i = pos + 1;
    while(i < sqlist->length)
    {
        sqlist->data[i-1] = sqlist->data[i];
        i--;
    }
    sqlist->length--;
    return true;
}
//头删
int DeleteSqList_Head(SqListPtr sqlist)
{
    return DeleteSqList_Pos(sqlist,0);
}
//删除(尾删)
int DeleteSqList_Tail(SqListPtr sqlist)
{
    if(sqlist == NULL)
        exit(0);
    return DeleteSqList_pos(sqlist,sqlist->length-1);
}

//打印
void ShowSqList(SqListPtr sqlist)
{
    if(sqlist == NULL) exit(0);
    for(int i=0;i<sqlist->length;i++)
    {
        printf("%d ",sqlist->data[i]);
    }
    printf("\n");
}
//清空
void ClearList_SqList(SqListPtr sqlist)
{
    if(sqlist == NULL)
        exit(0);
    sqlist->length = 0;
}
//销毁
void DestorySqList(SqListPtr sqlist)
{
    ClearList_SqList(sqlist);
}

 

2、不定长顺序表

结构:

typedef int ElemType;
typedef struct SqList
{
    ElemType *data;
    int length;//当前存储数据的个数
    int listsize;//存储空间
}SqList,*SqListPtr;

初始化:

#define SIZE 10

int InitSqList(SqListPtr sq)
{
    if(sq == NULL) exit(0);
    sq->length = 0;
    sq->data = (ElemType *)malloc(SIZE * sizeof(ElemType));
    if(sq->data == NULL) return false;
    sq->listsize = SIZE;

    return ture;
}

注意:不定长顺序表,当存储空间不够时,需要扩充空间,那该如何扩大呢?

/*
扩充内存:1、申请更大内存(一般扩充为原始大小的二倍)
         2、拷贝原始的数据
         3、释放原有的空间
         4、将新空间的首地址存储到sq->data上
*/
static int AppendSpace(SqListPtr sq)
{
    ElemType * data = (ElemType *)malloc(sq->listsize *sizeof(ElemType)*2);
    if(data == NULL) return false;
    sq->listsize *= 2;
    for(int i = 0;i<sq->length;i++)
    {
        data[i] = sq->data[i];
    }
    free(sq->data);
    sq->data = data;
    return ture;
}

实现功能:插入(头插、尾插、按位插入),删除(头删、尾删、按位删除),打印,销毁

//判满
static int Is_Full_SqList(SqListPtr sq)
{
    if(sq->data == NULL || sq->length == sq->listsize)
        return ture;
    return false;
}
//按位插入
int InsertSqList_Pos(SqListPtr sq,ElemType val,int pos)
{
    if(sq == NULL) exit(0);
    if(pos < 0 || pos > sq->length)
        return false;
    if(Is_Full_SqList(sq) && !AppendSpace(sq))
        return false;
    for(int i = sq->length;i>pos;i--;)//插入的位置之后的数统一向后移一个位置
    {
        sq->data[i] = sq->data[i-1];
    }
    sq->data[i] = val;
    sq->length++;
    return true;
}
//头插
int InsertSqList_Head(SqListPtr sq,ElemType val)
{
    return InsertSqList_Pos(sq,val,0);
}
//尾插
int InsertSqList_Tail(SqListPtr sq,ElemType val)
{
    if(NULL == sq) exit(0);
    return InsertSqList_Pos(sq,val,sq->length);
}

//按位删除
int DeleteSqList_Pos(SqListPtr sq,int pos)
{
    if(sq == NULL) exit(0);
    if(pos < 0 || pos >= sq->length)
        return false;
    while(pos < sq->length-1)//删除的位置之后的数统一向前移一个位置
    {
        sq->data[pos] = sq->data[pos+1];
    }
    sq->length--;
    return true;
}
//头删
int DeleteSqLsit_Head(SqListPtr sq)
{
    return DeleteSqList_Pos(sq,0);
}
//尾删
int DeleteSqList_Tail(SqListPtr sq)
{
    if(sq == NULL) exit(0);
    return DeleteSqList_POs(sq,sq->length-1);
}
//打印
void Show(SqListPtr sq)
{
    if(sq == NULL ) exit(0);
    for(int  i = 0;i<sq->length;i++)
    {
        printf("%d ",sq->data[i]);
    }
    printf("\n");
}
//销毁
void Destory(SqListPtr sq)
{
    if(NULL == sq) exit(0);
    
    free(sq->data);
    sq->data = NULL;//free之后再置为空,为了防止野指针出现
    sq->length = sq->listsize = 0;
}

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值