数据结构和算法

思维导图如下

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

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;


}

你可能感兴趣的:(数据结构和算法)