数据结构:预备理论知识+ 顺序表(超详细)

一.  数据结构理论知识:

                                                     程序 = 数据结构 + 算法

1.定义:数据结构是指数据与数据之间的逻辑结构、存储结构和运算操作。

逻辑结构:

主要是指数据与数据之间的逻辑物理关系:

线性关系:

数据与数据之间满足一对一的关系:

线性表、栈、队列

层次关系(树形关系):

数据与数据之间满足一对多的关系:

树、二叉树

网状关系(图形关系)

数据与数据之间满足多对多的关系:

存储结构:

数据在内存当中的存储方式

顺序存储:

在内存当中开辟一块连续的存储空间

链式存储:

数据在内存当中不需要开辟一块连续的空间

为了让数据与数据之间建立联系,我们把每一个数据称之为结点,结点有两部分组成:数据域和指针域,数据域保存数据,指针域保存后一个结点的地址。

索引存储:

哈希存储(散列表):

需要一个性能比较好的哈希函数(取随机数法、除留取余法等),需要有一个好的冲突处理方式(再哈希法、链地址法等)作为冲突处理方式。

运算操作:增、删、改、查

2 .算法的相关概念

2.1 算法的概念

实现某一个函数功能的方法(解决问题的办法)

2.2 算法的特性

1、算法的有穷性 —— 执行步骤是有穷的

2、算法的确定性 —— 计算步骤无二义性

3、算法的可行性 —— 每个计算步骤能够在有限的时间内完成

4、输入 —— 算法有一个或者多个输入

5、输出 —— 算法有一个或者多个输出

2.3 算法的分析

在保存算法正确无误的情况下,评价算法好坏的方法:

1、消耗时间的多少 —— 越少越好

2、耗费内存的多少 —— 越少越好

3、容易理解、容易调试、容易维护

4、时间复杂度 —— 越少越好

5、空间复杂度 —— 越少越好

2.4 时间复杂度

频度:一个代码执行的次数

1、for(i = 0;i < n; i++) 频度是 n+1

2、for(i = 0; i < n; i++)

for(j = 0; j < n; j++) 频度是 n (n + 1)

时间复杂度:一个代码所有的频度之和,用T(n)表示

T(n) = n + 1+ n(n +1 )= n^2 + 2n + 2 简写 T(n)= O(n^2)

线性表的存储:

线性表的顺序存储:顺序表

线性表的链式存储:链表

二.顺序表

1.概念

顺序表是线性表的顺序存储,需要开辟一块连续的空间,所以使用数组。

为了方便访问顺序表,我们需要定义一个变量last,用以存储最后一个数据的位置,后续代码(用last = -1编写)

2.顺序表代码流程梳理:

①创建一个空的顺序表

②插入数据

③遍历并打印数据

④判断顺序表是否为满

⑤判断顺序表是否为空

⑥删除数据,并返回数据

⑦根据数据修改数据

⑧根据位置修改数据

⑨根据位置查找数据

⑩根据数据查找位置

11.根据位置插入数据

12.

3.顺序表整体代码实现:

#include <stdio.h>
#include <stdlib.h>
#define N 10

typedef struct
{
    int data[N];
    int last;//last代表的是数组中最后一个有效元素的下标
}seqlist_t;

//1.创建一个空的顺序表
seqlist_t* CreateEpSeqlist();//返回的是申请空间的首地址

//2.向顺序表的指定位置插入数据
int InsertIntoSeqlist(seqlist_t* p, int post, int data);//post第几个位置,data插入的数据

//3.遍历顺序表sequence 顺序 list 表
void ShowSeqlist(seqlist_t* p);

//4.判断顺序表是否为满,满返回1 未满返回0
int IsFullSeqlist(seqlist_t* p);

//5.判断顺序表是否为空
int IsEpSeqlist(seqlist_t* p);

//6.删除顺序表中指定位置的数据post删除位置
int DeletePostSeqlist(seqlist_t* p, int post);

//7.清空顺序表
void ClearSeqList(seqlist_t* p);

//8.修改指定位置的数据
int ChangePostSeqList(seqlist_t* p, int post, int data);//post被修改的位置,data修改成的数据

//9.查找指定数据出现的位置
int SearchDataSeqList(seqlist_t* p, int data);//data代表被查找的数据

//10.合并表
void CombineAB(seqlist_t *p,seqlist_t *pb);

int main()
{
    seqlist_t* p = CreateEpSeqlist();//创建一个空的顺序表
    InsertIntoSeqlist(p, 0, 1);
    InsertIntoSeqlist(p, 1, 2);
    InsertIntoSeqlist(p, 2, 3);
    InsertIntoSeqlist(p, 3, 4);
    ShowSeqlist(p);//1 2 3 4
    DeletePostSeqlist(p, 1);
    ShowSeqlist(p);//1 3 4
    ChangePostSeqList(p, 1, 100);
    ShowSeqlist(p);//1 100 4
    int t;//承接查找数据的下标
    t=SearchDataSeqList(p, 100);
    printf("%d\n", t);//1

    seqlist_t* pb = CreateEpSeqlist();
    InsertIntoSeqlist(pb, 0, 1);
    InsertIntoSeqlist(pb, 1, 100);
    InsertIntoSeqlist(pb, 2, 200);
    InsertIntoSeqlist(pb, 3, 300);
    InsertIntoSeqlist(pb, 4, 400);
    ShowSeqlist(pb);
    CombineAB(p,pb);
    ShowSeqlist(p);
    return 0;
}

//1.创建一个空的顺序表
seqlist_t* CreateEpSeqlist()//返回的是申请空间的首地址
{
    //动态申请一块空间
    seqlist_t* p = (seqlist_t*)malloc(sizeof(seqlist_t));
    //sizeof(seqlist_t)计算结构体的大小
    if (p == NULL) {
        printf("申请空顺序表错误\n");
        return NULL;
    }
    //last是最后一个有效元素的下标
    p->last = -1;//空
    return p;
}

//4.判断顺序表是否为满,满返回1 未满返回0
int IsFullSeqlist(seqlist_t* p)
{
    return p->last + 1 == N;//成立返回1(满),不成立返回0
}

//2.向顺序表的指定位置插入数据
int InsertIntoSeqlist(seqlist_t* p, int post, int data)//post第几个位置,data插入的数据
{
    //1、容错判断
    //小于最小,大于最大;顺序表满了帮你插入
    if (post<0 || post>p->last+1|| IsFullSeqlist(p)) {
        printf("插入失败\n");
        return -1;//错误返回
    }
    //2、last-post往后移动一个位置
    int i;
    for (i = p->last; i >= post; i--) {
        p->data[i + 1] = p->data[i];
    }
    //3、插入数据
    p->data[post] = data;
    //4、p->last+1
    p->last++;
    return 0;
}

//3.遍历顺序表sequence 顺序 list 表
void ShowSeqlist(seqlist_t* p)
{
    int i;
    for (i = 0; i <= p->last; i++) {
        printf("%d ", p->data[i]);
    }
    printf("\n");
}

//5.判断顺序表是否为空
int IsEpSeqlist(seqlist_t* p)
{
    return p->last == -1;
}

//6.删除顺序表中指定位置的数据post删除位置
int DeletePostSeqlist(seqlist_t* p, int post)
{
    //1、容错判断
    if (post > p->last || post < 0 || IsEpSeqlist(p)) {
        printf("删除失败\n");
        return -1;
    }
    //2、post+1-last向前移动一个位置
    int i;
    for (i = post + 1; i <= p->last; i++) {
        p->data[i - 1] = p->data[i];
    }
    //3、有效元素-1
    p->last--;
    return 0;
}

//7.清空顺序表(清空:访问不到,但内存当中还有;销毁:内存清空)
void ClearSeqList(seqlist_t* p)
{
    p->last = -1;
}

//8.修改指定位置的数据
int ChangePostSeqList(seqlist_t* p, int post, int data)//post被修改的位置,data修改成的数据
{
    //1、容错判断
    if (post<0 || post>p->last) {
        printf("修改失败\n");
        return -1;
    }
    //2、修改指定位置数据
    p->data[post] = data;
}

//9.查找指定数据出现的位置
int SearchDataSeqList(seqlist_t* p, int data)//data代表被查找的数据
{
    int i;
    for (i = 0; i <= p->last; i++) {
        if (p->data[i] == data) {
            return i;
        }
    }
    return -1;
}
//10.合并表
void CombineAB(seqlist_t *p,seqlist_t *pb)
{
    int i;
    for(i=0;i<=pb->last;i++){
    if(SearchDataSeqList(p,pb->data[i])==-1){//没有找到
    InsertIntoSeqlist(p,p->last+1,pb->data[i]);
        }
    }
}


 2.单链表代码实现:

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值