数据结构和算法

思维导图如下

一、数据结构核心名称解释

1.逻辑结构:数据的逻辑结构是指数据元素之间的逻辑关系描述。根据数据元素之间的关系的不同特性,通常有四种基本逻辑结构:

a.集合结构:结构中的数据元素之间除了同属于一个集合的关系外,无任何其他关系。

b.线性结构:结构中的数据元素之间存在着一对一的线性关系。

c.树状结构:结构中数据元素之间存在着一对多的层次关系。

d.图状结构或网状结构:结构中的数据元素之间存在着多对多的任意关系。

1.1逻辑结构分为:

a.线性结构---线性表、栈、队、字符串、数组、广义表

b.非线性结构--数、图

2存储结构:(又称物理结构)是逻辑结构在计算机中的存储映像,包括数据元素映像和关系印映像,它是逻辑结构在计算机

二、逻辑结构和物理结构的区别

逻辑结构:实体数据元素间逻辑关系即实体性质理解基础进行抽象模型 

物理结构:数据元素计算机存储即计算机数据理解逻辑结构计算机语言映射

三、算法设计要求

1.算法的正确性。

2.可读性。

3.健壮性。

4.高效性和低存储量。

四、算法效率衡量方法

1.时间复杂度:为了便于比较解决同一个问题的不同算法,通常以算法中击败操作重复执行的频度作为度量标准;常见的时间复杂度如下图:

2空间复杂度:算法空间复杂度的计算公式记作(Space Complexity):S(n) = O(f(n)),其中n是问题规模,f(n)为语句关于n所占存储空间的函数。

如当一个算法的空间复杂度为一个常量,即不随被处理数据量n的大小而改变时,可表示为O(1);当一个算法的空间复杂度与以2为底的n的对数成正比时,可表示为0(10g2n);当一个算法的空I司复杂度与n成线性比例关系时,可表示为0(n)。


3.算法的性能选择:

a.诺该程序适用次数较少,则力求算法精明易懂。

b.对于反复使用的程序,应尽可能使用快速的算法。

c.诺待解决的问题数据量极大,计算机的存储空间较小,则相应算法主要考虑如何节省空间。

八、线性表--关于顺序存储的实现(增删改查)

1.结构体的创建

typedef struct {

    ElemType*data;

    intlength;

}Sqlist;


2.顺序表初始化

StatusInitList(Sqlist*L){

    //为顺序表分配一个大小为MAXSIZE 的数组空间

    L->data=  malloc(sizeof(ElemType) *MAXSIZE);

    //存储分配失败退出

    if(!L->data)exit(ERROR);

    //空表长度为0

    L->length=0;

    return OK;

}

3.顺序表的插入

/*

 初始条件:顺序线性表L已存在,1≤i≤ListLength(L);

 操作结果:在L中第i个位置之前插入新的数据元素e,L的长度加1

 */

StatusListInsert(Sqlist*L,inti,ElemTypee){

    //i值不合法判断

    if((i<1) || (i>L->length+1))returnERROR;

    //存储空间已满

    if(L->length==MAXSIZE)returnERROR;

    //插入数据不在表尾,则先移动出空余位置

    if(i <= L->length){

        for(intj = L->length-1; j>=i-1;j--){

            //插入位置以及之后的位置后移动1位

            L->data[j+1] = L->data[j];

        }

    }

    //将新元素e 放入第i个位置上

    L->data[i-1] = e;

    //长度+1;

    ++L->length;

    return OK;

}

4. 顺序表的取值

StatusGetElem(SqlistL,inti,ElemType*e){

    //判断i值是否合理, 若不合理,返回ERROR

    if(i<1|| i > L.length)return  ERROR;

    //data[i-1]单元存储第i个数据元素.

    *e = L.data[i-1];

    return OK;

}

5.顺序表的删除

/*

 初始条件:顺序线性表L已存在,1≤i≤ListLength(L)

 操作结果: 删除L的第i个数据元素,L的长度减1

 */

StatusListDelete(Sqlist*L,inti){


    //线性表为空

    if(L->length==0)returnERROR;


    //i值不合法判断

    if((i<1) || (i>L->length+1))returnERROR;


    for(intj = i; j < L->length;j++){

        //被删除元素之后的元素向前移动

        L->data[j-1] = L->data[j];

    }

    //表长度-1;

    L->length--;

    return OK;

}


6. 清空顺序表

/* 初始条件:顺序线性表L已存在。操作结果:将L重置为空表 */

StatusClearList(Sqlist*L)

{

    L->length=0;

    return OK;

}

7. 判断顺序表清空

/* 初始条件:顺序线性表L已存在。操作结果:若L为空表,则返回TRUE,否则返回FALSE */

StatusListEmpty(SqlistL)

{

    if(L.length==0)

        return TRUE;

    else

        return FALSE;

}

8. 获取顺序表长度ListEmpty元素个数 */

intListLength(SqlistL)

{

    returnL.length;

}

//1.8 顺序输出List

/* 初始条件:顺序线性表L已存在 */

/* 操作结果:依次对L的每个数据元素输出 */

StatusTraverseList(SqlistL)

{

    inti;

    for(i=0;i

        printf("%d\n",L.data[i]);

    printf("\n");

    return OK;

}

9. 顺序表查找元素并返回位置

/* 初始条件:顺序线性表L已存在 */

/* 操作结果:返回L中第1个与e满足关系的数据元素的位序。 */

/* 若这样的数据元素不存在,则返回值为0 */

intLocateElem(SqlistL,ElemTypee)

{

    inti;

    if(L.length==0)return0;

    for(i=0;i

    {

        if(L.data[i]==e)

            break;

    }

    if(i>=L.length)return0;

    returni+1;

}

九、线性表==关于链式(单链表)存储的设计(增删改查与头插法/尾插法)

//定义结点

typedef struct Node{

    ElemTypedata;

    structNode*next;

}Node;

typedefstructNode* LinkList;

//2.1 初始化单链表线性表

StatusInitList(LinkList*L){


    //产生头结点,并使用L指向此头结点

    *L = (LinkList)malloc(sizeof(Node));

    //存储空间分配失败

    if(*L ==NULL)returnERROR;

    //将头结点的指针域置空

    (*L)->next=NULL;


    return OK;

}

//2.2 单链表插入

/*

 初始条件:顺序线性表L已存在,1≤i≤ListLength(L);

 操作结果:在L中第i个位置之后插入新的数据元素e,L的长度加1;

 */

StatusListInsert(LinkList*L,inti,ElemTypee){


    intj;

    LinkListp,s;

    p = *L;

    j =1;


    //寻找第i-1个结点

    while(p && j

        p = p->next;

        ++j;

    }


    //第i个元素不存在

    if(!p || j>i)returnERROR;


    //生成新结点s

    s = (LinkList)malloc(sizeof(Node));

    //将e赋值给s的数值域

    s->data= e;

    //将p的后继结点赋值给s的后继

    s->next= p->next;

    //将s赋值给p的后继

    p->next= s;


    return OK;

}

//2.3 单链表取值

/*

 初始条件: 顺序线性表L已存在,1≤i≤ListLength(L);

 操作结果:用e返回L中第i个数据元素的值

 */

Status GetElem(LinkList L,int i,ElemType *e){


    //j: 计数.

    intj;

    //声明结点p;

    LinkList p;


    //将结点p 指向链表L的第一个结点;

    p = L->next;

    //j计算=1;

    j =1;



    //p不为空,且计算j不等于i,则循环继续

    while(p && j


        //p指向下一个结点

        p = p->next;

        ++j;

    }


    //如果p为空或者j>i,则返回error

    if(!p || j > i)returnERROR;


    //e = p所指的结点的data

    *e = p->data;

    return OK;



}

//2.4 单链表删除元素

/*

 初始条件:顺序线性表L已存在,1≤i≤ListLength(L)

 操作结果:删除L的第i个数据元素,并用e返回其值,L的长度减1

 */

StatusListDelete(LinkList*L,inti,ElemType*e){


    intj;

    LinkListp,q;

    p = (*L)->next;

    j =1;


    //查找第i-1个结点,p指向该结点

    while(p->next&& j<(i-1)) {

        p = p->next;

        ++j;

    }


    //当i>n 或者 i<1 时,删除位置不合理

    if(!(p->next) || (j>i-1))return  ERROR;


    //q指向要删除的结点

    q = p->next;

    //将q的后继赋值给p的后继

    p->next= q->next;

    //将q结点中的数据给e

    *e = q->data;

    //让系统回收此结点,释放内存;

    free(q);


    return OK;

}

/* 初始条件:顺序线性表L已存在 */

/* 操作结果:依次对L的每个数据元素输出 */

StatusListTraverse(LinkListL)

{

    LinkList p=L->next;

    while(p)

    {

        printf("%d\n",p->data);

        p=p->next;

    }

    printf("\n");

    return OK;

}

/* 初始条件:顺序线性表L已存在。操作结果:将L重置为空表 */

StatusClearList(LinkList*L)

{

    LinkListp,q;

    p=(*L)->next;          /*  p指向第一个结点 */

    while(p)                /*  没到表尾 */

    {

        q=p->next;

        free(p);

        p=q;

    }

    (*L)->next=NULL;        /* 头结点指针域为空 */

    return OK;

}

//3.1 单链表前插入法

/* 随机产生n个元素值,建立带表头结点的单链线性表L(前插法)*/

voidCreateListHead(LinkList*L,intn){


    LinkList p;


    //建立1个带头结点的单链表

    *L = (LinkList)malloc(sizeof(Node));

    (*L)->next=NULL;


    //循环前插入随机数据

    for(inti =0; i < n;i++)

    {

        //生成新结点

        p = (LinkList)malloc(sizeof(Node));


        //i赋值给新结点的data

        p->data= i;

        //p->next = 头结点的L->next

        p->next= (*L)->next;


        //将结点P插入到头结点之后;

        (*L)->next= p;


    }

}

//3.2 单链表后插入法


/* 随机产生n个元素值,建立带表头结点的单链线性表L(后插法)*/

voidCreateListTail(LinkList*L,intn){


    LinkListp,r;


    //建立1个带头结点的单链表

    *L = (LinkList)malloc(sizeof(Node));

    //r指向尾部的结点

    r = *L;


    for(inti=0; i


        //生成新结点

        p = (Node*)malloc(sizeof(Node));

        p->data= i;


        //将表尾终端结点的指针指向新结点

        r->next= p;

        //将当前的新结点定义为表尾终端结点

        r = p;

    }


    //将尾指针的next = null

    r->next=NULL;


}

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 160,387评论 4 364
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,845评论 1 298
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 110,091评论 0 246
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,308评论 0 214
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,662评论 3 288
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,795评论 1 222
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 32,008评论 2 315
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,743评论 0 204
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,466评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,687评论 2 249
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,181评论 1 262
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,531评论 3 258
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,177评论 3 239
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,126评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,902评论 0 198
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,862评论 2 283
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,734评论 2 274

推荐阅读更多精彩内容