嵌入式 线性表(顺序表,链表)示例

除第一个元素外,其他每一个元素有一个且仅有一个直接前驱;

除最后一个元素外其他每一个元素有一个且仅有一个直接后继。

这就是线性表的基本特征了。

那顺序表和链表有是什么呢?

顺序表和链表都是线性表。

首先说下顺序表:其实很简单,就是像数组一样,数据存放在连续的存储空间中。

用数组就能很方便的实现这种结构。

所以,因为储存结构的顺序与逻辑结构的顺序完全一致,其最大优点就是可以方便地随机存取表中任一个结点。

就像数组可以直接用下表来对数组进行操作。

但是,这一个又有一个很大的缺点:既然储存结构的顺序与逻辑结构的顺序完全一致,那么,当我们想在中间插入或者在中间删除一个数据的时候,我们就要将该位置以后的所有数据都向后移,或者向前移。效率就有点低了吧。还有一个问题:当我们定义一个数组的什么时候,比如:intstr[N];N是一个给定的数,也就是说,我要给他分配一块固定的空间,那么,当我们不知道要多少空间的时候,我们有可能会让费空间,或者空间不够用。

这样就要说到链表了,它是线性表的链接存储表示可不连续地分布在内存中任何的位置。

链表(单链表,双链表,(循环,带头))

我这篇博客就说说单链表了~~~~~

1.单链表结点:

  1. <spanstyle="font-size:18px;">typedefintNodeData;
  2. typedef structnode
  3. {
  4. NodeData data;
  5. struct node*next;
  6. }NODE;</span>
typedef int NodeData;

typedef struct node
{
    NodeData data;
    struct node *next;
}NODE;


本来不打算说的,后来想想,还是写上去,只想推荐使用typedef

2.单链表的create,insert,remove,sort都不说了

3.我只想说下单链表的转置(很多公司面试题都会问这个):

  1. <spanstyle="font-size:18px;">NODE * myreverse(NODE*head)
  2. {
  3. if(head == NULL||head->next == NULL)
  4. {
  5. returnhead;
  6. }
  7. else
  8. {
  9. NODE *front = NULL;
  10. NODE *q = head;
  11. while(q !=NULL)
  12. {
  13. NODE *ne = NULL;
  14. ne = q->next;
  15. q->next = front;
  16. front = q;
  17. q = ne;
  18. }
  19. returnfront;
  20. }
  21. }</span>
NODE * myreverse(NODE *head)
{
    if(head == NULL ||head->next == NULL)
    {
        return head;
    }
    else
    {
        NODE *front = NULL;
        NODE *q = head;
        while(q != NULL)
        {
            NODE *ne = NULL;
            ne = q->next;              
            q->next = front;           
            front = q;                 
            q = ne;                    
        }
    return front;
    }
}

这个应该还是很重要的,能完全熟练掌控最好,不能的话就背下来呗,反正也不长。

最后,还是 多画画图,对学数据结构太有用了。

<think>嗯,用户想了解顺序表的静态分配实现。我需要先回忆一下数据结构中顺序表的相关知识。顺序表是一种线性表的顺序存储结构,通常用数组来实现。静态分配应该是指数组的大小在编译时就确定好了,无法在运行时动态调整。 首先,我应该解释什么是顺序表,然后对比静态分配和动态分配的区别。静态分配使用固定长度的数组,而动态分配可以根据需要扩容。接着,可能需要给出静态分配的具体实现步骤,比如定义结构体,包含数据数组和长度变量。 然后,要考虑用户可能的疑问,比如静态分配的优缺点。优点可能是实现简单,不需要频繁的内存管理;缺点则是容量固定,可能浪费空间或不够用。需要举例说明,比如用C语言的结构体来定义,包含一个固定大小的数组和一个记录当前长度的整型变量。 还要提到基本操作,比如初始化、入、删除、查找等。在入和删除时,需要移动元素,时间复杂度是O(n),而访问元素是O(1)。这些都需要在回答中说明,帮助用户全面理解。 另外,需要确保使用正确的中文术语,比如“顺序表”而不是“链表”,并且代码示例要符合语法规范。静态分配的代码示例应该展示如何定义数组和长度,以及如何进行基本操作,比如入元素时的步骤:检查位置是否合法,检查是否已满,然后移动元素并入。 可能用户是刚学习数据结构的学生,所以需要结构清晰,分步骤解释,避免使用过于专业的术语,或者适当解释术语。比如解释“随机存取”是什么意思,为什么顺序表支持这一点。 最后,总结静态分配的适用场景,比如元素数量已知且变化不大的情况,不适合需要频繁入删除或元素数量变化大的情况。这样用户能根据实际需求选择合适的实现方式。</think>顺序表的静态分配实现详解(分步骤说明) 一、基本概念 顺序表是一种线性数据结构,采用连续的存储空间存放元素。静态分配指在编译阶段预先分配固定大小的存储空间,数组长度不可变。 二、结构体定义(C语言示例) ```c #define MAX_SIZE 100 // 预定义最大容量 typedef struct { int data[MAX_SIZE]; // 静态分配数组 int length; // 当前元素个数 } SqList; ``` 三、核心特性 1. 存储结构 - 物理存储:连续内存空间 - 逻辑结构:线性排列 - 索引访问:支持随机存取,时间复杂度 $O(1)$ 2. 容量特性 - 固定容量:由 `MAX_SIZE` 定义 - 空间预分配:程序启动即分配内存 - 空间利用率:实际使用量 ≤ MAX_SIZE 四、基本操作实现 1. 初始化 ```c void InitList(SqList *L) { L->length = 0; // 初始长度为0 } ``` 2. 入操作(时间复杂度 $O(n)$) 步骤: (1) 检查入位置合法性:$1 \leq i \leq L.length+1$ (2) 判断是否已满:$L.length == MAX_SIZE$ (3) 元素后移:从第 $L.length$ 个元素到第 $i$ 个元素依次后移 (4) 入新元素 (5) 长+1 3. 删除操作(时间复杂度 $O(n)$) 步骤: (1) 检查删除位置合法性:$1 \leq i \leq L.length$ (2) 元素前移:从第 $i+1$ 个元素到最后一个元素依次前移 (3) 长-1 五、优缺点对比 优点: - 内存管理简单(无动态分配开销) - 存取速度快(支持随机访问) - 存储密度高(无需额外指针空间) 缺点: - 容量固定(可能浪费或不足) - 入/删除效率低(需移动大量元素) - 扩容困难(需要重新创建更大数组) 六、适用场景 1. 数据规模可预估且变化不大 2. 需要频繁随机访问元素 3. 对内存碎片敏感的环境 4. 对运行稳定性要求高的系统(避免动态分配失败) 七、典型应用示例 1. 学生成绩(固定班级人数) 2. 传感器数据缓存(预知采样频率) 3. 嵌入式系统存储(内存受限环境) 八、补充说明 虽然静态分配实现简单,但在实际工程中更常用动态分配方式(通过 `malloc/realloc` 实现),以提升空间利用率。静态分配适合用于教学演示或对内存有严格要求的场景。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值