数据结构学习记录——Day1 顺序表

学习教程为华清创客学院,秦老师的《数据结构全攻略》

定义:零个或多个相同数据元素的有限序列。

表示:

8种基本操作:

1. 建立空表

2. 置空一个表

3. 判断是否为空

4. 求表长

5. 取表中元素

6. 定位元素位置

7. 插入

8. 删除

合并运算和去重运算:

C语言中,顺序表的实现是用的一维数组。因为二者都是连续存储的。

 顺序存储结构的特点:
-(1)逻辑上相邻的元素ai,ai+1,其存储位置也是相邻的;
-(2)对数据元素ai的存取为随机存取或按地址存取。
-(3)存储密度高。存储密度D=(数据结构中元素所占存储空间)/(整个数据结构所占空间)。
顺序存储结构的不足:
-对表的插入和删除等运算的时间复杂度较差。

对顺序表的各种操作是用指针来实现的。

 last为指向表尾的指针,置为-1表示当前表为空表。

下面是代码实现,首先要建立头文件,对这些函数进行声明。

#ifndef __SEQLIST_H__
#define __SEQLIST_H__

#define MAXSIZE 100
typedef int data_t;
typedef struct{
    data_t data[MAXSIZE];
    int last;
}seqlist_t;        //建立结构体,包含表尾指针和一维数组

seqlist_t *create_seqlist(void);    //建立顺序表,申请一段存储空间
void clear_seqlist(seqlist_t *L);    //释放顺序表,返还存储空间

int is_empty_seqlist(seqlist_t *L);    //判断是否为空
int is_full_seqlist(seqlist_t *L);    //判断是否为满
void set_empty_seqlist(seqlist_t *L);    //清空顺序表
int get_lenth_seqlist(seqlist_t *L);    //求表长度
void show_seqlist(seqlist_t *L);    //打印顺序表

int insert_seqlist(seqlist_t *L, data_t x, int pos); //插入一个元素
int delete_seqlist(seqlist_t *L, int pos);        //删除一个元素
int change_seqlist(seqlist_t *L, data_t x, int pos); //修改某个元素
int search_seqlist(seqlist_t *L, data_t x);        //查找某个元素位置

#endif

头件的中的#ifndef,这是一个很关键的东西。

需要注意的是,#ifndef起到的效果是防止一个源文件两次包含同一个头文件,而不是防止两个源文件包含同一个头文件。在编译时,这两个C文件要一同编译成一个可运行文件,会产生大量的声明冲突
把头文件的内容都放在#ifndef和#endif中间,不管你的头文件会不会被多个文件引用,都要加上这个。

声明完成后,编写C文件来实现

#include<stdio.h>
#include<stdlib.h>
#include"seqlist.h"    //自己的项目内的头文件要用双引号

seqlist_t *create_seqlist(void){
    seqlist_t *L = NULL;        //定义一个空指针
    L = (seqlist_t *)malloc(sizeof(seqlist_t)); //申请堆栈空间
    //malloc返回是void型,要强制类型转换,给指针L
    if(L == NULL){
        puts("no memory");
        return NULL;
    }        //申请失败提示信息,后面每个函数都需要判断

    L->last = -1;    //初始化时last置为-1,因为数组下标是从0开始的
    return L;        //建表函数返回一个指向表头的指针
}

void clear_seqlist(seqlist_t *L){
    if(L == NULL){
        puts("seqlist_t *L is NULL");
    }
    free(L);        //释放掉这段空间
    return ;
}

int is_empty_seqlist(seqlist_t *L){
    if(L==NULL){
        puts("seqlist *L is NULL");
        return -1;
    }
    return(L->last == -1);   //判断是否为空只要看last是否和初始时的值一样
}

int is_full_seqlist(seqlist_t *L){
    if(L == NULL){
        puts("seqlist_t *L is NULL");
        return -1;
    }
    return (L->last == MAXSIZE-1);   //比较last指针的值和表最大长度,注意下标从0开始
}

void set_empty_seqlist(seqlist_t *L){
    if(L==NULL){
        puts("seqlist *L is NULL");
        return;
    }
    L->last = -1;        
    //置空时不用管现存元素,直接把last置为-1,后面再插入的时候就从data[0]开始重写了
    return;
}

int get_lenth_seqlist(seqlist_t *L){
    if(L==NULL){
        puts("seqlist *L is NULL");
        return -1;
    }
    return(L->last+1);    //获取表长,直接last+1

}

void show_seqlist(seqlist_t *L){
    int i;
    if(L == NULL){
        puts("seqlist_t *L is NULL");
        return ;
    }
    for(i = 0; i<=L->last; i++)        //for循环依次打印即可
        printf("L->data[%d] = %d\n", i, L->data[i]);
    return ;

}

int insert_seqlist(seqlist_t *L, data_t x, int pos){
    int i;
    if((is_full_seqlist(L))||(pos<0)||(pos>L->last+1)){
        puts("input pos is invalid");
        return -1;
    }    //首先判断表是否为满,或者插入位置pos的值是否正确
    for(i = L->last; i>=pos; i--)    //从最后的元素开始往下一个移动,否则会删除原有数据
        L->data[i+1] = L->data[i];    //这一个数据来覆盖后面一个位置个位置
    L->data[pos] = x;            //然后把中间pos空出来的位置赋上数值x
    L->last++;                //注意把表尾指针往后移一格
    return 0;
}

int delete_seqlist(seqlist_t *L, int pos){    //参数pos,删除该位置的数据
    if(pos<0||pos>L->last){
        puts("input pos is invalid");
        return -1;
    }    //判断pos是否正确
    int i;
    for(i = pos; i <= get_lenth_seqlist(L); i++){  //从pos开始,把后面的数据往前移一格
        L->data[i] = L->data[i+1];
    }
    L->last--;                 //移动完成后,将last也往前移一格

    return 0;
}

int change_seqlist(seqlist_t *L, data_t x, int pos){
    if(pos<0||pos>L->last){
        puts("input pos is invalid");
        return -1;
    }        //还是先判断pos合理性
    L->data[pos] = x;        //修改pos位置的数据
    return 0;
}

int search_seqlist(seqlist_t *L, data_t x){
    int i;
    for(i = 0; i <= L->last; i++){
        if(L->data[i] == x)
            return i;
    }        //从data[0]开始遍历,返回匹配的下标
    return -1;    //如果没有匹配的,返回-1
}

最后编写测试程序来验证上述函数结果:

#include<stdio.h>
#include<stdlib.h>
#include"seqlist.h"

int main(int argc, const char * argv[]){
    int i = 0;
    seqlist_t *L = NULL;
    L = create_seqlist();
    for(i = 0; i<=4; i++)
        insert_seqlist(L, i, 0);    //写入数值
    show_seqlist(L);            //打印出当前线性表
    printf("===============================\n");
    printf("data 3 pos is %d\n", search_seqlist(L, 3));
    printf("seqlist L lenth is %d\n", get_lenth_seqlist(L));
    puts("===============================");
    puts("delete data=3");
    delete_seqlist(L, search_seqlist(L, 3));    //pos位置参数用search函数返回值来表示
    show_seqlist(L);
    puts("===============================");
    puts("change data[2] = 99");
    change_seqlist(L, 99, 2);
    show_seqlist(L);
    clear_seqlist(L);
    return 0;
}

运行结果:

stephen@subuntu:~/Desktop/Data Stru/line/seqlist$ ./test
L->data[0] = 4
L->data[1] = 3
L->data[2] = 2
L->data[3] = 1
L->data[4] = 0
===================================
data 3 pos is 1
seqlist L lenth is 5
===================================
delete data=3
L->data[0] = 4
L->data[1] = 2
L->data[2] = 1
L->data[3] = 0
===================================
change data[2] = 99
L->data[0] = 4
L->data[1] = 2
L->data[2] = 99
L->data[3] = 0

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值