数据结构:线性表之顺序表

本文介绍了一种基于数组实现的线性表——顺序表。详细解释了如何利用指针数组来存储person结构体实例,实现了增删改查等功能。探讨了时间复杂度,并对比了不同操作的效率。

数据结构:线性表之顺序表

需求:实现线性表的数组方式实现,

功能:实现数组表的增删改查

实现:

将各个功能单独封装到函数

  • 初始化:由于数据都不是在主函数中创建,出函数后无法使用。所以元素和元素集合(person and men)使用动态内存创建。
  • 增:将person结构体封装到men结构体中,以指针数组方式存储,每次添加一个元素并记录表长,
  • 删:删除元素,并移动元素填补空位。更新表长。释放内存。时间复杂度 O(n)
  • 改:由于是指针数组,更改指针指向,释放内存即可,(未实现)
  • 查:遍历表元素,对比元素内容(compareP())返回下标。时间 复杂度 O(n)
  • 插入:移动元素得到空位,再插入元素。时间复杂度 O(n)

总结:

    线性表的数组实现是最简单的顺序存储结构,其元素顺序存储在内存中。即逻辑结构和存储结构相同
由于这次实现用的是指针数组,所以元素是分散存储的。不知还算不算顺序表。

算法分析:
    数组结构的删除和插入都需要移动元素,在最坏情况下要移动整个表,最好情况下无需移动。所以时间复杂的为 O(n)
效率并不高。查找算法需要遍历数组,所以复杂度也是O(n)。
数组结构的优势在于其数据是连续存储在内存中,通过指针运算可以快速访问数组任意 指定 位置的元素。
适合按下标访问,删除和插入元素较少的场景

最后感慨两句:Java的垃圾回收机制实现的内存管理确实大大方便了程序开发。

头文件代码如下:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifndef PERSON_H_INCLUDED
#define PERSON_H_INCLUDED

#define max 10

typedef struct {
    char name[10];
    short age;
}person;

typedef struct {
    person *p[max];
    int length;
}men;


#endif // PERSON_H_INCLUDED

demo 代码如下:

#include "person.h"
//初始化 person, 返回person指针
person *newP(char *name,int age){
    //检查参数
    if(name == NULL)return NULL;
    //动态分配内存
    person *p = (person *)malloc(sizeof(person));
    p->age = age;
    strcpy(p->name,name);
    return p;
}

//初始化线性表, 返回表men结构指针
men *newM(){
    men *m = (men *)malloc(sizeof(men));
    m->length = 0;//length代表可存储元素的位置的下标
    return m;
}

//添加元素 返回逻辑值(是否成功添加元素)
int add(men *m, person *p){
    //检查参数
    if(m == NULL || p == NULL)exit(1);

    if(m->length < max){
        m->p[m->length++] = p;
        return 1;
    }
    printf("person size don't enough , need more size !!!");
    return 0;
}

//插入元素 返回逻辑值(是否成功插入元素)
int insert(men *m,person *p,int index){
    //检查参数
    if(m == NULL || p == NULL)exit(1);

    if(index >= 0 && index < m->length){
        int i;
        //move 元素
        //从下标length开始,交换p[length]和p[length-1];直到下标递减到index时,便腾出了一个空位(index)
        for(i = m->length++; i > index; i--){
            m->p[i] = m->p[i-1];
        }

        //insert  元素
        m->p[i] = p;
        return 1;
    }
    printf("index error !!!");
    return 0;
}

//删除元素 返回逻辑值(是否成功delete元素)
int myremove(men *m,int index){
    //检查参数
    if(m == NULL)exit(1);

    if(index >= 0 && index < m->length){
        int i,j;
        //释放内存
        free(m->p[index]);

        //remove 元素
        //从下标index开始交换P[index]和P[index+1]。直到length-1.
        for(i = --(m->length),j = index; j < i; j++){
            m->p[j] = m->p[j+1];//注意!!p[++j]不可用,取到的值还是j
             //printf("test%d,%d\n",++index,index++);//?打印结果5,3 7,5
        }
        return 1;
    }
    printf("index error !!!");
    return 0;
}

//查找元素 返回下标(如果找到元素)或-1(没找到)
int locateP(men *m,person *p){
    int i, j;
    //遍历数组比较元素,找到返回下标
    for(i = 0, j = m->length; i < j; i++){
        if(compareP(m->p[i],p)){
            return i;
        }
    }
    return -1;
}

//person元素比较器 返回逻辑值(元素是否相同)
int compareP(person *p1,person *p2){
    if(p1 == p2){
        return 1;
    }

    return (p1->age == p2->age && !strcmp(p1->name,p2->name));
}

void println(men *m){
    int i, length = m->length;
    for (i = 0; i < length; i++){
        printf("%d ,name = %s,age = %d\n", i, m->p[i]->name, m->p[i]->age);

    }
    printf("**************************************\n");
}

int main()
{
    person p1 = {"df",14};

    //初始化
    int *p,i;
    men *m = newM();
    add(m,newP("",NULL));//测试传null
    add(m,newP("ww",13));
    add(m,newP("ww",13));
    add(m,newP("df",14));
    add(m,newP("zs",15));

    //求表长
    printf("length = %d\n",m->length);
    //遍历元素
    println(m);
    //插入元素
    insert(m,newP("new",3),2);
    println(m);
    //删除元素
    myremove(m,3);
    println(m);
    //查找元素
    printf("index = %d\n",locateP(m,&p1));

    return 0;

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值