顺序表(可扩容)

1、可扩容顺序表

结构设计
#define INIT_SIZE 100 //设置每次扩展的容量
​
//顺序表结构内容
​
typedefintELEM_TYPE;//设置顺序表中所存储的内容
​
//设置顺序表结构的内容
typedefstructSqlist
{
    ELEM_TYPE*elem;//设置顺序表的头指针,指向使用malloc所创建的内存地址
    intlength;//保存此时顺序表中所存储的内容
    intlist_size;//此时顺序表的长度
}Sqlist,*PSqlist;
初始化
数据插入方式,有三种(头插、尾插、按位置插)
//顺序表初始化
voidInit_Sqlist(PSqlistsq)
{
    //指针判空
    assert(sq!=NULL);
​
    //使用elem接受malloc所创建的内存
    sq->elem= (ELEM_TYPE*)malloc(INIT_SIZE*sizeof(ELEM_TYPE));
    assert(sq->elem!=NULL);
​
    //有效长度设置
    sq->length=0;
​
    //顺序表容量设置
    sq->list_size=INIT_SIZE;
}
头插
//头插
boolInsert_head(PSqlistsq, ELEM_TYPEval)
{
    //指针判空
    assert(sq!=NULL);
​
    //判满操作
    if (IsFull(sq))//为真则进行扩容操作
    {
        Inc(sq);
    }
​
    //头插,则需要将顺序表所存储的内容向后移动
    for (inti=sq->length-1; i>=0; i--)//因此出length并不代表顺序的所有长度,因此进行i+1操作不会出现错误
    {
        sq->elem[i+1] =sq->elem[i];
    }
​
    //进行头插
    sq->elem[0] =val;
​
    //有效长度加一
    sq->length++;
​
    returntrue;
}
尾插
//尾插
boolInsert_tail(PSqlistsq, ELEM_TYPEval)
{
    assert(sq!=NULL);
​
    if (IsFull(sq))
    {
        Inc(sq);
    }
​
    sq->elem[sq->length] =val;
​
    sq->length++;
​
    returntrue;
}
按位置插入
//按位置插入
boolInsert_pos(PSqlistsq, intpos, ELEM_TYPEval)//结构体指针sq,插入位置pos(此处的pos是值得从0开始算起的位置),插入指val
{
    assert(sq!=NULL);
​
    assert(pos>=0&&pos<=sq->length);//此处<=为sq->length,是因为当超过此长度时,插入时会出现空挡,不连续
​
    if (IsFull(sq))
    {
        Inc(sq);
    }
​
    for (inti=sq->length-1; i>=pos; i--)//将插入位置之后的内容
    {
        sq->elem[i+1] =sq->elem[i];
    }
​
    sq->elem[pos] =val;
    sq->length++;
    
    returntrue;
}
数据删除方式,有四种(头删、尾删、按位置删、按值删)
头删
//头删
boolDel_head(PSqlistsq)
{
    assert(sq!=NULL);
​
    if (IsEmpty(sq))
    {
        returnfalse;
    }
​
    for (inti=1; i<sq->length; i++)
    {
        sq->elem[i-1] =sq->elem[i];
    }
​
    sq->length--;
    
    returntrue;
}
尾删
//尾删
boolDel_tail(PSqlistsq)
{
    assert(sq!=NULL);
​
    if (IsEmpty(sq))
    {
        returnfalse;
    }
​
    sq->length--;//此处不用对尾部数据进行操作,只要对有效长度进行操作,即可达到数据删除的效果
​
    returntrue;
}
按位置删
//按位置删
boolDel_pos(PSqlistsq, intpos)
{
    assert(sq!=NULL);
​
    assert(pos>=0&&pos<=sq->length);//所删除位置在有效的范围内
​
    if (IsEmpty(sq))
    {
        returnfalse;
    }
​
    for (inti=pos+1; i<=sq->length; i++)
    {
        sq->elem[i-1] =sq->elem[i];
    }
​
    sq->length--;
​
    returntrue;
}
按值删
//按值删
bool Del_val(PSqlist sq, ELEM_TYPE val)
{
    assert(sq != NULL);

    if (IsEmpty(sq))
    {
        return false;
    }

    int pos = Search(sq, val);

    if (pos == -1)
    {
        return false;
    }

    return Del_pos(sq, pos);
}
功能设计
按值查找
//按值查找
bool Search(PSqlist sq, ELEM_TYPE val)
{
    assert(sq != NULL);

    for (int i = 0; i < sq->length; i++)
    {
        if (sq->elem[i] == val)
        {
            return i;
        }
        else
        {
            return false;
        }
    }
}
判空和判满操作
//判空
bool IsEmpty(PSqlist sq)
{
    assert(sq != NULL);

    return sq->length == 0;
}

//判满
bool IsFull(PSqlist sq)
{
    assert(sq != NULL);

    return sq->length == sq->list_size;
}
扩容操作
//扩容操作
bool Inc(PSqlist sq)
{
    assert(sq != NULL);

    sq->elem = (ELEM_TYPE*)realloc(sq->elem, sq->list_size * sizeof(ELEM_TYPE) * 2);//realloc(原指针,扩容大小)
    assert(sq->elem != NULL);

    sq->list_size *= 2;//此处的扩容使递增的,如第一次是100,第二次则是200,第三次是400,第四次是800···第n次是100(2^n - 1)

    return true;
}
清空销毁操作
//清空
void Clear(PSqlist sq)
{
    assert(sq != NULL);

    sq->length = 0;//清空即是将有效值设置为0
}

//销毁,释放内存
void Des(PSqlist sq)
{
    assert(sq != NULL);

    sq->length = sq->list_size = 0;

    free(sq->elem);
}
打印
//打印
void Print(PSqlist sq)
{
    assert(sq != NULL);

    for (int i = 0; i < sq->length; i++)
    {
        printf("第%d个 -> %d\n", i, sq->elem[i]);
    }
}
可扩容顺序表的优缺点
优点:

1.支持随机访问

2.尾插和尾删效率高

缺点:

1.头插头删,中间插入,中间删除,效率低

2.扩容代价高:申请,拷贝,释放

使用场景

适用于需要大量随机访问数据元素,并插入和删除操作大都是在尾部进行的。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值