数据结构入门之线性表---干货满满

一、什么是线性表

线性表是一种基本的数据结构,用于存储一组具有相同特征的元素。它的元素按照线性顺序排列,支持对元素的访问和操作。线性表的特点包括:

1. 线性关系:元素之间存在一对一的关系,每个元素(除第一个和最后一个外)都有一个前驱和后继元素。

2. 动态性和静态性:线性表可以通过不同的方式实现:
           顺序表(数组):使用连续的内存空间来存储元素,支持随机访问,但在插入和删除操作时可能需要移动大量元素。
           链表 :通过节点(包含数据和指向下一个节点的指针)来存储元素,插入和删除操作效率较高,但前提是需要遍历链表来访问特定元素。

3. 基本操作:线性表支持的基本操作包括:
   - 插入:在指定位置插入元素。
   - 删除:删除指定位置的元素。
   - 查找:查找指定元素的位置。
   - 遍历:按顺序访问所有元素。

二、顺序表(代码)
        

   一、初始化表(创建一个表)

//定义一个结构体(表)
typedef struct seqlist{
    int data[MAX_SIZE];
    int last;
    int num;
}Seqlist;

//表的初始化 
Seqlist* Seqlist_init(){
    Seqlist *list = (Seqlist *)malloc(sizeof(Seqlist));
    if(NULL == list){
        return NULL;
    }
    list->last=-1;
}

表的定义是通过我们开辟一个堆空间,其中放入的是我们定义的结构体变量,last表示表指针,data表示我们需要插入进去的数据,我们用一个数组将其保存下来

二、插入元素

//判断是否为满,如果满则返回1,否则为0 
int Seqlist_is_Full(Seqlist *p){
    return p->last+1 == MAX_SIZE;
}
//增加元素  
void Seqlist_insert(Seqlist *p,int num,int pos){
    if(Seqlist_is_Full(p) == 1){
        printf("表已满,无法继续插入数据!\n");
        return ;
    }
    if(pos > p->last+1 || pos < 0){
        printf("请插入到正确的位置!\n");
        return ;
    }
    for(int i=p->last;i>=pos;i--){
        p->data[i+1] = p->data[i];
    }
    p->last = p->last+1; 
    p->data[pos] = num;
}
  1. 顺序表的满状态检查

    if(Seqlist_is_Full(p) == 1)

    • 这是一个重要的边界条件检查。顺序表的数组存储空间是固定的,因此在插入新元素之前必须确认是否还有空间。这防止了数组越界的问题,确保了内存的安全。
  2. 位置有效性验证

    if(pos > p->last + 1 || pos < 0)

    • 在顺序表中,插入的位置需要在合法范围内。合法的位置包括:
      • 从 0 到 last(表示最后一个有效元素的索引)之间的值,表示新元素会插入在已有元素之间。
      • 还允许在 last + 1 位置插入,表示新元素将在最后一个元素之后。这种检查防止了无效的内存写入。
  3. 元素移动的逻辑

    for(int i = p->last; i >= pos; i--)

    • 从后往前移动元素是一个关键步骤。这一做法确保已经有的位置不会被覆盖。在移动过程中,只有当目标位置的元素存在时,才需要移动。这种反向移动策略非常有效,因为它避免了在逐个移动的过程中影响未处理的元素,确保了数据的一致性。
  4. 更新 last 的重要性

    p->last = p->last + 1;

    • 在插入元素后,更新 last 索引的值是必要的。这确保顺序表的状态保持最新,反映出当前存储的有效元素数量。这对于后续插入、删除等操作非常重要,使得其他操作能够正确地知道当前数据的范围。

三、删除元素

//判断是否为空 ,如果空则返回1,否则为0  
int Seqlist_is_Empty(Seqlist *p){
    return p->last == -1;
} 
//删除元素
void seqlist_del(Seqlist *p,int pos){
     if(Seqlist_is_Empty(p) == 1){
        printf("list is empty!\n");
        return ;
     }
     if(pos > p->last+1 || pos < 0){
        printf("del is error\n");
     }
    for(int i=pos;i<p->last;i++){
        p->data[i] = p->data[i+1];
    }
    p->last = p->last-1;
}

删除表元素和上面插入表元素其实操作差不多,不过这个时候我们需要判断表中是否含有元素

我们就通过Seqlist_is_Empty()这个函数判断

四、修改元素

//修改元素
void seqlist_change(Seqlist *p,int pos,int num){
    if(Seqlist_is_Empty(p)==1){
        printf("list is empty can not change!\n");
        return ;
    }
    if(pos > p->last+1 || pos > 0){
        printf("pos is error\n");
        return ;
    }
    p->data[pos] = num;
}

当我们前面的内容理解之后,那么修改元素也非常简单,我们还是一样先判断表中是否有元素,还有我们修改的位置是否正确,接下来是直接将我们输入位置对应的下标赋值给我们需要修改的值就可以成功

五、查询元素

//查询元素 
void seqlist_search(Seqlist *p,int pos){
    if( Seqlist_is_Empty(p)==1 ){
        printf("list is empty can not search\n");
        return ;
    }
    if(pos > p->last+1 || pos < 0){
        printf("pos is error can not search\n");
        printf("last num:%d\n",p->last);
        return ;
    }
    printf("search num is :%d\n",p->data[pos]);
}

查润元素直接打印对应下标元素的值就可以

六、删除指定元素

//删除指定元素
void seqlist_del_num(Seqlist *p,int num){
    
    printf("you want del:%d\n",num);

    if( Seqlist_is_Empty(p)==1 ){
        printf("list is empty can not del num\n");
        return ;
    }

    int sum = 0;
    for(int i=0;i <= p->last;i++){
        if(p->data[i] == num){
            sum++;
            for(int j=i;j<= p->last;j++){
                p->data[j] = p->data[j+1];
            }
        }
    }
    if(sum == 0){
        printf("do not have this num\n");
    }
    p->last = p->last - sum;
}
  1. 空表检查:首先检查顺序表是否为空。如果为空,则打印一条信息并返回,表示无法删除元素。

  2. 循环遍历:接下来,通过一个循环遍历顺序表中的所有元素:

    • 如果当前元素等于要删除的元素num,就增加sum的计数,表示找到了一个要删除的元素。
  3. 元素移位:在找到要删除的元素后,使用另一个循环将该元素之后的所有元素前移一个位置,以覆盖被删除的元素。

  4. 更新表的大小:最后,根据找到的要删除的元素的数量更新顺序表的最后一个元素的索引(last),减少已删除元素的数量。

  5. 未找到信息:如果在循环中没有找到任何要删除的元素,打印信息表示该元素不存在。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值