数据结构——顺序表

 ACM大牛带你玩转算法与数据结构-课程资料

 本笔记属于船说系列课程之一,课程链接:

哔哩哔哩_bilibiliicon-default.png?t=N7T8https://www.bilibili.com/cheese/play/ep66799?csource=private_space_class_null&spm_id_from=333.999.0.0

你也可以选择购买『船说系列课程-年度会员』产品『船票』,畅享一年内无限制学习已上线的所有船说系列课程:船票购买入口icon-default.png?t=N7T8https://www.bilibili.com/cheese/pages/packageCourseDetail?productId=598

做题网站OJ:HZOJ - Online Judge

Leetcode :力扣 (LeetCode) 全球极客挚爱的技术成长平台

数据结构是什么

        数据机构是计算机存储、组织数据的一种方式,他是将逻辑关系和物理关系它们的相互关系结合在一起,并利用这种关系实现在计算机上来对数据的存储和组织,并对他们做出适当的计算和做出一些优秀的算法,但最终不会改变数据的结构类型;      

        数据结构 = 结构定义 + 结构操作

        结构定义:

        结构定义分为两个物理结构和逻辑结构

        物理结构定义,在数据结构的静态部分,它定义了数据元素之间的关系和布局,以及每个元素的属性。例如这个文章中的顺序表,他的物理结构定义就是:

typedef struct Vector {
    int size;//顺序表的长度
    int len;//顺序表现有的元素个数
    void *data;//数据存储区
} Vector;

        而它的逻辑结构定义就是,每个元素物理结构和逻辑结构都是连续的,也就是每个元素之间的地址也是连续的;

        结构操作:

        结构操作就是在不破坏结构定义的前提下,去对定义结构里的数据进行操作,比如增删改查;例如对于顺序表的插入元素:

        

int add_element(Vector *v, int ind, int val) {//插入元素
    //在顺序表的ind位置插入元素val
    if (!v) return 0;
    if (ind < 0 || ind > v->len) return 0;//因为元素之间必须连续,所以插入元素位置必须在[0, v->len)区间内
    if (v->len == v->size) return 0;//超过了结构定义的长度,无法再插入元素,这里可以去扩容,这里你们自己实现以下,也是对自己对能力的提升
    for (int i = v->len; i > ind; i--) {//将ind位置和以后的位置向后移,将ind的位置空出来放val
        v->data[i] = v->data[i - 1];
    }
    v->data[ind] = val;
    (v->len)++;
    return 1;
} 

顺序表 

        大概讲述了以下数据结构是什么,现在来说顺序表;

        顺序表就是把它里面的元素的物理结构,逻辑结构都是连续起来的,也就是他们的地址是连续的,在我们的思想里也是连续的;

        它其实和数组是差不太多的,但是它里面存了元素,每个元素是必须连续的,而数组你可以想存在那个数组的位置就可以存在那个位置,没有结构定义的逻辑限制;所以我上面说了在对结构操作时不能去违背结构定义;不然就像你女朋友给你买了一包搽脸巾,而你拿来擦py;你破坏了结构定义,就是你违背了你女朋友的想法;

        不要想着去违背女人的想法,所以不要去违背结构定义,这样你就会很轻松的拿捏女朋友,呸,数据结构;

        顺序表的物理结构定义很简单

        1.他的总长度

        2.他现在的长度

        3.连续存储元素的空间(也就是数组)

        而它的逻辑结构定义就是,元素的物理结构,逻辑结构都是连续起来的;

        有了这几个条件就可以去实现顺序表了,然后我用的是C语言,因为C语言没有封装好的这些数据结构,只能通过自己去实现定义啊,操作啊这些,当你能用C语言自己来实现这些东西了,你用封装好的那不是手手到擒来;

顺序表结构的操作:

        插入操作:

        元素6要插入到位置2

        先把位置2以及位置2以后的元素向后移动一位,把位置2空出来

        然后将位置2给元素6,并且顺序表的元素个数+1

删除操作:

        将位置3的元素删除后

        再将位置3后的元素进行向前移动一个位置,并且元素个数-1

  代码实现:

#include <stdio.h>
#include <time.h>
#include <stdlib.h>

typedef struct Vector {
    int size;//顺序表的长度
    int len;//顺序表现有的元素个数
    int *data;//数据存储区
} Vector;

Vector *init(int n) {//向计算机借空间,记得还回去
    Vector *v = (Vector *)calloc(sizeof(Vector), 1); 
    v->data = (int *)calloc(sizeof(int), n);
    v->size = n;
    v->len = 0;
    return v;
}

int add_element(Vector *v, int ind, int val) {
    if (!v) return 0;
    if (ind < 0 || ind > v->len) return 0;//因为元素之间必须连续,所以插入元素位置必须在[0, v->len)区间内   
    if (v->len == v->size) return 0;//超过了结构定义的长度,无法再插入元素,这里可以去扩容,这里你们自己实现以下,也是对自己对能力的提升    
    for (int i = v->len; i > ind; i--) {//讲ind位置和以后的位置向后移,讲ind的位置空出来放val
        v->data[i] = v->data[i - 1];
    }
    v->data[ind] = val;
    (v->len)++;
    return 1;
} 

int erase(Vector *v, int ind) {//删除ind位置的元素
    if (!v) return 0;
    if (ind < 0 || ind >= v->len) return 0;//删除肯定要删除区间里的元素,区间外是没有元素的
    for (int i = ind + 1; i < v->len; i++) {//直接从ind + 1往前覆盖,最终覆盖掉ind位置的元素
        v->data[i - 1] = v->data[i];
    }
    (v->len)--;
    return 1;
}

void output(Vector *v) {
    if (!v) return ;
    printf("Vector(%d) = [", v->len);
    for (int i = 0; i < v->len; i++) {
        i && printf(",");
        printf("%d", v->data[i]);
    }
    printf("]\n");
    return ;
}


void clear(Vector *v) {//你用了就要还回去,你是借的计算机的不是你的
    if (!v) return ;
    free(v->data);
    free(v);
    return ;
}


int main() {//测试
    srand(time(0));
    Vector *v = init(10);
    int op, ind, val;
    for (int i = 0; i < 20; i++) {
        op = rand() % 4;//1/4概率删除,3/4概率添加
        ind = rand() % (v->len + 2) - 1;
        val = rand() % 100;
        switch (op) {
            case 0:
            case 1:
            case 2: {
               printf("%d insert in Vector %d is %d\n", val, ind, add_element(v, ind, val)); 
            } break;

            case 3: {
                printf("erase in Vector %d is %d\n", ind, erase(v, ind));
            } break;
        }
        output(v);
    }
    clear(v);//最后记得释放动态开辟的空间!!数据结构基本都会动态开辟空间
    return 0;
}

小结:

        顺序表对于数组的优势就是可以进行元素的插入和删除,还可以直接获取到元素的个数,而且不仅仅是现在实现的两个操作,还有如果顺序表的容量不够了,那么可以进行扩容操作,还可以实现操作在顺序表的头部加入元素等等操作。顺序表对应C++的STL容器vector,而在vector容器中,实现了很多对于vector的结构操作。假如没有学数据结构,那使用vector容器就会没有那么顺手了。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

初猿°

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值