嵌入式学习的第十八天-数据结构-绪论+算法+线性表

一、数据结构绪论

1.定义

相互之间存在一种或多种特定关系的数据元素的集合。

2.逻辑结构与物理结构

(1)逻辑结构

  • 集合,所有数据在同一个集合中,关系平等。
  • 线性,数据和数据之间是一对一的关系
  • 树, 一对多
  • 图,多对多

(2)物理结构(在内存当中的存储关系)

  • 顺序存储,数据存放在连续的存储单位中。逻辑关系和物理关系一致
  • 链式,数据存放的存储单位是随机或任意的,可以连续也可以不连续。
struct Per 数据元素
{
char name;//数据项
int age;
char phone;
}

struct Per list[100]; //数据对象
3.抽象数据类型

(1)数据的类型,ADT    abstruct datatype 定义

         是指一组性质相同的值的集合及定义在此集合上的一些操作的总称。

(2)分类

  • 原子类型,int,char,float
  • 结构类型,sturct, union

(3)抽象数据类型, 数学模型 + 操作。程序 =  数据 + 算法

二、算法

1.定义

算法是解决特定问题求解步骤的描述,计算机中表现为指令的有限序列,每条指令表示一个或多个

操作。


2.算法的特征

(1)输入,输出特性,输入时可选的,输出时必须的。

(2)有穷性,执行的步骤会自动结束,不能是死循环,并且每一步是在可以接受的时间内完成。

(3)确定性,同一个输入,会得到唯一的输出。

(4)可行性,每一个步骤都是可以实现的。

2.算法的设计

(1)正确性
        1)语法正确

         2)合法的输入能得到合理的结果

        3)对非法的输入,给出满足要求的规格说明

         4)对精心选择,甚至刁难的测试都能正常运行,结果正确

(2)可读性,便于交流,阅读,理解

(3)健壮性,输入非法数据,能进行相应的处理,而不是产生异常

(4)高效,存储低,效率高 

3.算法时间复杂度

  也就是执行这个算法所花时间的度量   1  = O(n)   O(1)

   O(1)<O(logn)<O(N)<O(nlogn)<O(n^2)<O(n^3)<O(2^n)<O(n!)<O(n^n)

   eg: n =O(n); n^3 =O(n^3) ;

        for()  n
       {
       for()   n
        }

4.推导时间复杂度

(1)用常数1 取代运行时间中的所有加法常数

(2)在修改后的运行函数中,只保留最高阶项。

(3)如果最高阶存在且不是1,则取除这个项相乘的常数。

三、线性表

1.定义

零个或者多个数据元素的有限序列

2.特征

(1)元素之间是有顺序了。如果存在多个元素,第一个元素无前驱,最有一个没有后继,其他的

         元素只有一个前驱和一个后继。

(2)当线性表元素的个数n(n>=0)定义为线性表的长度,当n=0时,为空表。在非空的表中每个

         元素都有一个确定的位置,如果a1是第一个元素,那么an就是第n个元素。

3.线性表顺序存储的常规操作  ADT
typedef struct person {
char name[32];
char sex;
int age;
int score;
}DATATYPE;
typedef int Datatype;
typedef struct list {
DATATYPE *head;
int tlen;
int clen;
}SeqList;

SeqList *CreateSeqList(int len);//创建顺序表
int DestroySeqList(SeqList *list);//销毁数据链(整个)
int ShowSeqList(SeqList *list);//数组遍历b表
int InsertTailSeqList(SeqList *list, DATATYPE *data);//尾插,在顺序表的最后插入元素
int IsFullSeqList(SeqList *list);//判断是否满
int IsEmptySeqList(SeqList *list);//判断是否空
int InsertPosSeqList(SeqList *list, DATATYPE *data, int pos);//按指定位置插入元素
int FindSeqList(SeqList *list, char *name);//查找元素,根据名字
int ModifySeqList(SeqList *list, char *old, DATATYPE *newdata);//根据名字修改指定元素
int DeleteSeqList(SeqList *list, char *name);//根据名字删除指定元素
int ClearSeqList(SeqList *list);//清空表,清空表中已有元素(结构在,数据删除)
int GetSizeSeqList(SeqList *list);//获得表中有效元素个数
DATATYPE *GetItemSeqList(SeqList *list,int ind);//获得指定下标元素本身

注:内存泄露检测工具

sudo apt-get install valgrind
valgrind ./all 
4.线性表顺序存储的优点,缺点

(1)优点

  • 1,无需为表中的逻辑关系增加额外的存储空间
  • 2,可以快速随机访问元素O(1)

(2)缺点

  • 1,插入,删除元素需要移动元素o(n)
  • 2,无法动态存储
5..手撕上述代码

(1)seqlist.c

#include "seqlist.h"
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
SeqList *CreateSeqList(int len)
{
    SeqList *sl = malloc(sizeof(SeqList));
    if(NULL == sl)
    {
        fprintf(stderr,"CreateSeqList malloc error\n");
        return NULL;
    }

    sl->head = malloc(sizeof(DATATYPE)*len);

     if(NULL == sl->head)
    {
        fprintf(stderr,"CreateSeqList malloc2 error\n");
        return NULL;
    }

    sl->tlen = len;
    sl->clen = 0;
    return sl;
}

int IsFullSeqList(SeqList *list)
{
    if(NULL == list)
    {
        fprintf(stderr,"IsFullSeqList paramter error\n");
        return 1;
    }
    return list->clen == list->tlen;    
}    

int InsertTailSeqList(SeqList *list, DATATYPE *data)
{
    if(IsFullSeqList(list))
    {
      fprintf(stderr, "seqList full\n");
      return 1;  
    }

    memcpy(&list->head[list->clen],data,sizeof(DATATYPE));
    //list->head[list->clen] = *data;
    list->clen++;
    return 0;   
} 

int ShowSeqList(SeqList *list)
{
    int len = GetSizeSeqList(list);
    int i = 0;
    for(i = 0;i < len;++i)
    {
        printf("%s %c %d %d\n",list->head[i].name,list->head[i].sex,list->head[i].age,list->head[i].score);
    }
    return 0;
}

int GetSizeSeqList(SeqList *list)
{
    return list->clen;
}

int IsEmptySeqList(SeqList *list)
{
    return 0 == list->clen;//双等号常量放左边
}

int FindSeqList(SeqList *list, char *name)
{
    int i = 0;
    int len = GetSizeSeqList(list);
    for(i = 0;i < len;++i)
    {
        if(0 == strcmp(list->head[i].name,name))
        {
            return i;
        }
    }
    return -1;
}

DATATYPE *GetItemSeqList(SeqList *list,int ind)
{
    if(NULL == list)
    {
        return NULL;
    }

    int len = GetSizeSeqList(list);
    if(ind<0 || ind>len)
    {
        return NULL;
    }

    return &list->head[ind];
}

int InsertPosSeqList(SeqList *list, DATATYPE *data, int pos)
{
    if(IsFullSeqList(list))
    {
        return 1;
    }
    int len = GetSizeSeqList(list);
    if(pos < 0 || pos > len)
    {
        return 1;
    }
    int i = 0;
    for(i = list->clen;i > pos;--i)
    {
        memcpy(&list->head[i],&list->head[i - 1],sizeof(DATATYPE));
    }
    memcpy(&list->head[pos],data,sizeof(DATATYPE));
    list->clen++;
    return 0;
}


int DeleteSeqList(SeqList *list, char *name)
{
    if(IsEmptySeqList(list))
    {
        return 1;
    }
    int ret = FindSeqList(list, name);
    if(-1 == ret)
    {
        return 1;
    }
    int i = 0;
    int len = GetSizeSeqList(list);
    for(i = ret;i < len - 1;++i)
    {
       memcpy(&list->head[i],&list->head[i + 1],sizeof(DATATYPE)); 
    }
    list->clen--;
    return 0;
}

int ModifySeqList(SeqList *list, char *old, DATATYPE *newdata)
{
    if(IsEmptySeqList(list))
    {
        return 1;
    }
    int ret = FindSeqList(list, old);
    if(-1 == ret)
    {
        return 1;
    }
    memcpy(&list->head[ret],newdata,sizeof(DATATYPE));
    return 0;
}

int ClearSeqList(SeqList *list)
{
    list->clen = 0;
    return 0;
}

int DestroySeqList(SeqList *list)
{
    if(NULL == list)
    {
        return 1;
    }
    free(list->head);
    free(list);
    return 0;
}

(2)seqlist.h

#ifndef _SEQLIST_H_
#define _SEQLIST_H_

typedef struct person {
char name[32];
char sex;
int age;
int score;
}DATATYPE;
typedef int Datatype;
typedef struct list {
DATATYPE *head;
int tlen;
int clen;
}SeqList;

SeqList *CreateSeqList(int len);//创建顺序表
int DestroySeqList(SeqList *list);//销毁数据链(整个)
int ShowSeqList(SeqList *list);//数组遍历b表
int InsertTailSeqList(SeqList *list, DATATYPE *data);//尾插,在顺序表的最后插入元素
int IsFullSeqList(SeqList *list);//判断是否满
int IsEmptySeqList(SeqList *list);//判断是否空
int InsertPosSeqList(SeqList *list, DATATYPE *data, int pos);//按指定位置插入元素
int FindSeqList(SeqList *list, char *name);//查找元素,根据名字
int ModifySeqList(SeqList *list, char *old, DATATYPE *newdata);//根据名字修改指定元素
int DeleteSeqList(SeqList *list, char *name);//根据名字删除指定元素
int ClearSeqList(SeqList *list);//清空表,清空表中已有元素(结构在,数据删除)
int GetSizeSeqList(SeqList *list);//获得表中有效元素个数
DATATYPE *GetItemSeqList(SeqList *list,int ind);//获得指定下标元素本身
#endif

(3)main.c

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

int main(int argc,char **argv)
{
    SeqList*s1 = CreateSeqList(5);

    DATATYPE data[] = {
        {"zhang",'F',20,80},
        {"lisi",'M',21,83},
        {"wang",'F',22,83},
        {"guanerge",'M',40,90},
        {"liubei",'M',41,92},
    };

    InsertTailSeqList(s1, &data[0]);
    InsertTailSeqList(s1, &data[1]);
    InsertTailSeqList(s1, &data[2]);

    ShowSeqList(s1);

    //InsertPosSeqList(s1, &data[3],1);
    DeleteSeqList(s1, "lisi");
    printf("................\n");
    ShowSeqList(s1);
    // int ret = FindSeqList(sl, "lisi");
    // if(-1 == ret)
    // {
    //     printf("not find\n");
    // }
    // else
    // {
    //     DATATYPE *tmp = GetItemSeqList(sl,ret);
    //     printf("%s %d\n",tmp->name,tmp->score);
    // }

    return 0;
}

:head:数组名,是指针指向首元素地址;

       tlen:总长度;

       clen:当前长度,代表使用的有效长度;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值