数据结构基础,算法基础,线性表

数据结构大纲

数据结构、算法(理解)、

线性表:顺序表(由数组构建)

链表(单向列表,单向循环列表,双向列表,双向循环列表)

栈(顺序栈,链式栈)

队列(循环队列,链式列)

树:特性、二叉树(性质、创建、遍历)

排序方法、查询方法(原理思路)

一、为什么学习数据结构

  1. c语言如何写程序

更简介高效写程序

  1. 如果遇到一个实际问题,需要写代码实现相应的功能,需要解决两个方法问题:

1)如何表达数据之间的逻辑关系以及怎么存储到计算机中。

数据结构:如何表达数据之间的逻辑关系,以及存储操作(数据的运算)

数据:不再是单纯的数字,而是集合的概念。

结构:数据之间的关系。

2)采用什么方法解决?

采用方法解决

数据结构加算法等于程序

  • 数据结构基础

1什么是数据结构

数据的逻辑结构以及存储操作。

数据结构没有想象的这么复杂,它就教会你:如何更有效的存储数据。

2数据

数据:不再是单纯的数字了,而是类似于集合的概念。

数据元素:数据的基本单位,数据元素由若干个数据项组成。

数据项:数据的最小单位,描述数据元素的有用的信息。

数据元素又叫节点

例如:

计算机处理的对象(数据)已不再是单纯的数值:

图书管理中的数据,如下表所列:

数据结构基础,算法基础,线性表_第1张图片

数据:图书

数据元素:每一本书

数据项:编号 书名 作者 出版社 出版日期

3数据结构分类

3.1逻辑结构

数据元素并不是孤立存在的,他们之间存在着某种关系(或者说结构,联系)

元素和元素之间的关系:

1)线性关系:

线性结构==>一对一,一个接着一个==>线性表:顺序表、列表、栈、队列

数据结构基础,算法基础,线性表_第2张图片

2)层次关系:

树形结构:==>一对多==>树:二叉树

数据结构基础,算法基础,线性表_第3张图片

3)网状关系:

图状结构:==>多对多==>图

数据结构基础,算法基础,线性表_第4张图片

例题:

田径比赛的时间安排问题

数据结构基础,算法基础,线性表_第5张图片

A

B

C

D

E

F

1

A

B

E

2

C

D

C

D

3

C

C

E

F

4

A

D

D

F

5

B

F

人员

项目

1

A

B

E

2

C

D

3

C

E

F

4

A

D

F

5

B

F

A/C

B/D

E

F

腾讯文档-流程图插件

数据结构基础,算法基础,线性表_第6张图片

4存储结构

数据的逻辑结构在计算机中的具体实现

4.1顺序存储

数组:连续存储

特点:内存连续、随机存取、每个元素占用空间较少。

4.2 链式存储

通过指针存储:

特点:内存不连续,通过指针去实现。

链表实现:通过结构体实现

数据结构基础,算法基础,线性表_第7张图片

#include 
struct node
{
    int data;          //数据域:存放节点数据
    struct node *next; //指针域:结构提指针,指向下一个节点。(自身结构体类型指针)
};

int main(int argc, char const *argv[])
{
    /*定义3个节点*/
    struct node A = {1, NULL};
    struct node B = {2, NULL};
    struct node C = {3, NULL};
    A.next = &B; //通过A的指针域存B的地址,把A和B相连
    B.next = &C; //通过B的指针域存C的地址,把B和C相连
    return 0;
}

4.3索引存储结构

存数据的同时,建立一个附加的索引表。

索引存储结构=索引表+数据文件

可以提高查找速度,检索速度快,但是占用内存多,删除数据文件要及时修改索引表。

数据结构基础,算法基础,线性表_第8张图片

这样查找一个电话就可以先查找索引表,再查找对应的数据文件,加快了查询的速度。但是如果删除或添加某个数据也要操作对应的索引表。

4.4散列存储

数据存储按照和关键码之间的关系进行存取,关系由自己决定,比如关键码是key,存储位置也就是关系是key+1.获取数据,也通过关系位置和关键码key之间的关系来获取。

存的时候按关系存,取的时候按关系取。

5操作

增删改查

  • 二、算法基础

  1. 什么是算法

解决问题的思想方法

数据结构+算法=程序

  1. 算法的设计

算法的设计:取决于数据的逻辑结构

算法的实现:依赖于数据在计算机中的存储结构

  1. 特性

有穷性:步骤是有限的

确定性:每一个步骤都有明确的含义,无二义性。

可行性:在规定时间内能完成

输入:

输出:

  1. 如何评价算法的好坏

(1)正确性

(2)易读性

(3)健壮性:容错处理

(4)高效性:算法执行效率,通过重复执行的次数来判断,也就是通过时间复杂度(时间处理函数)来判断。

时间复杂度:

语句频度:时间规模函数表达式

时间规模函数:T(n)=O(f(n))

T(n)//时间规模的时间函数

O//时间数量级

n//问题的规模,例如:a[100],n=100;

f(n)//算法可执行语句重复执行的次数

称O(f(n)) 为算法的渐进时间复杂度,简称时间复杂度。

渐进时间复杂度用大写O来表示,所以也被称为大O表示法。直白的讲,时间复杂度就是把时间规模函数T(n)简化为一个数量级,如n,n^2,n^3。

例子1:

算法1:

求1+2+3+4+...+n的和

int sum=0;
for(int i=1;i<=n;i++)		
{
	sum+=i;
}

n=100 100次

f(n)=n

==>T(n) = O(n)

算法2:

利用等差数列前n项和公式:Sn=n*a1+n(n-1)d/2  或 Sn=n(a1+an)/2 (d是公差)

int sum=n*(1+n)/2;//假设当n=100,重复执行一次

f(n)=1

T(n)=O(1)

例2:

int i,j;
for(i=0;i<n;i++)
{
	 for(j=0;j<n;j++)
    {
	    printf("ok\n);       
    }
}

f(n)=n*n

T(n)=O(n*n)

例3:

int i,j;
for(i=0;i<n;i++)
{
    for(j=0;j<=i;j++)
    {
        printf("ok\n");
    }
}

f(n)=n*(n+1)/2=n*n/2+n/2

T(n)=O(n*n)//只保留最高项,除以最高项系数

计算大O的方法

  1. 根据问题规模n写出表达式f(n)
  2. 如果有常数项,将其置为1    //当f(n)的表达式中只有常数项的时候,例如f(n)=8 ==> O(1)
  3. 只保留最高项,其他项舍去。
  4. 如果最高项系数不为1,则除以最高项系数。

f(n) = 3*n^4 + 2*n^3 + 6*n^7 +10

T(n)=O(n^7)

  • 三、线性表

1)概念:线性表是最基本最简单也是最常用的一种数据结构,可以存储逻辑关系为线性的数据 线性表(linear list)是数据结构的一种,一个线性表是n个具有相同特性的数据元素的 有限序列。

2)包含:顺序表(数组)、链表(单向列表、单向循环列表、双向列表、双向循环列表)

    栈(顺序栈、链式栈)、队列(循环队列、链式队列)

3)逻辑结构:线性结构

  1. 存储结构:顺序存储(数组)、链式存储(指针)
  2. 特点:一对一,每个节点最多可以有一个前驱和一个后继,首节点无前驱,尾节点无后继。
  1. 顺序表SeqList

顺序表存储数据的具体实现方案是:将数据全部存储到一整块内存空间中,数据元素之间按照次序挨个存放。

1.1顺序表的特性

逻辑结构:线性结构

存储结构:顺序存储

特点:内存连续,大小是固定的。

操作:增删改查

1.2数组操作

例题:

int a[100]={1,2,3,4,5,6,7,8};

函数命名规则:

下划线法:create_empty_seqlist

小驼峰法:createEmptySeqList

大驼峰法:CreateEmptySeqList

#include 

/*  (1)插入数组元素
    功能:向数组的第几个位置插数据
    函数:void insetIntoA(int *p,int n, int post, int data);
    参数:
    int *p: 保存数组首地址
    int n: 有效数据元素的个数
    int post: 插入元素下标
    int data: 数据
*/
void insertIntoA(int *p, int n, int post, int data)
{
    //1. 把从最后一个元素p[n-1]到插入位置元素p[post]向后移动一个单位
    for (int i = n - 1; i >= post; i--)
        p[+ 1] = p[i];
    //2. 插入新元素data到指定位置
    p[post] = data;
}

/*  (2)遍历数组
    功能:遍历数组中的有效元素
    函数:void showA(int *p,int n);
    参数:
    int *p:保存数组收地址
    int n:有效数据元素的个数
*/
void showA(int *p, int n) //p=a,n=8;
{
    int i;
    for (= 0; i < n; i++)
        printf("%d ", p[i]);
    printf("\n");
}

/*  (3)删除数组元素
    功能:删除数组中指定元素 
    函数:void deleteIntoA(int *p,int n, int post);
    参数:
    int *p: 保存数组首地址
    int n: 有效数据元素的个数
    int post: 删除元素下标
*/
void deleteIntoA(int *p, int n, int post) //a的值 9 4
{
    int i;
    //从删除位置的后一个元素p[post+1]到最有后一个元素p[n-1]往前移动一个单位
    for (= post + 1; i < n; i++) //for(i=4+1;i<9;i++)
        p[- 1] = p[i];
}
int main(int argc, char const *argv[])
{
    int a[100] = {1, 2, 3, 4, 5, 6, 7, 8};
    showA(a, 8);
    insertIntoA(a, 8, 2, 100);
    showA(a, 9);
    deleteIntoA(a, 9, 4);
    showA(a, 8);
    return 0;
}

插入元素不会增加空间,导致元素丢失

删除元素不会减少遍历。

数据结构基础,算法基础,线性表_第9张图片

1.3 数组操作优化:通过添加全局变量

添加全局变量last表示最后一个有效元素下标

#include 
int last = 7; //代表最后一个有效元素得下标 last=有效元素个数-1

/*  (1)插入数组元素
    功能:向数组的第几个位置插数据
    函数:void insetIntoA(int *p,int post, int data);
    参数:
    int *p: 保存数组首地址
    int post: 插入元素下标
    int data: 数据
*/
void insertIntoA(int *p, int post, int data)
{
    //1. 把从最后一个元素p[last]到插入位置元素p[post]向后移动一个单位
    for (int i = last; i >= post; i--)
        p[+ 1] = p[i];
    //2. 插入新元素data到指定位置
    p[post] = data;
    //3. 最后一个有效元素下标+1
    last++;
}

/*  (2)遍历数组
    功能:遍历数组中的有效元素
    函数:void showA(int *p);
    参数:
    int *p:保存数组收地址
*/
void showA(int *p)
{
    int i;
    for (= 0; i <= last; i++)
        printf("%d ", p[i]);
    printf("\n");
}

/*  (3)删除数组元素
    功能:删除数组中指定元素 
    函数:void deleteIntoA(int *p,int post);
    参数:
    int *p: 保存数组首地址
    int post: 删除元素下标
*/
void deleteIntoA(int *p, int post)
{
    int i;
    //1.从删除位置的后一个元素p[post+1]到最有后一个元素p[last]往前移动一个单位
    for (= post + 1; i <= last; i++)
        p[- 1] = p[i];
    //2.将最后一个有效元素下标减一
    last--;
}
int main(int argc, char const *argv[])
{
    int a[100] = {1, 2, 3, 4, 5, 6, 7, 8};
    showA(a);    //1 2 3 4 5 6 7 8
    insertIntoA(a, 2, 100);
    showA(a);    //1 2 100 3 4 5 6 7 8
    deleteIntoA(a, 4);
    showA(a);    //1 2 100 3 5 6 7 8 
    return 0;
}

数据结构基础,算法基础,线性表_第10张图片

1.4顺序表的实现

数据结构基础,算法基础,线性表_第11张图片

#include 
#include 

#define N 10
typedef int datatype;//int a; <==> datatype a;
typedef struct seqlist
{
    datatype data[N];    //相当于int data[N];
    int last; //代表数组中最后一个有效元素得下标
} seqlist_t;
//struct seqlist s; 相当于 seqlist_t s;

//创建空顺序表
seqlist_t *CreateEpSeqlist()
{
    //1.动态申请一块空间存放顺序表
    seqlist_t *= (seqlist_t *)malloc(sizeof(seqlist_t));
    if (NULL == p)
    {
        perror("CreateEpSeqlist p malloc err");
        return NULL;
    }
    //2.对last初始化
    p->last = -1;
    return p;
}

//向顺序表的指定位置插入
int InsertIntoSeqlist(seqlist_t *p, int post, int data)
{
    //1.容错判断
    //2.从下标为post到last的元素往后移动一个单位
    //3.插入数据
    //4.让last加一
}

int main(int argc, char const *argv[])
{
    seqlist_t *= CreateEpSeqlist();

    return 0;
}

你可能感兴趣的:(数据结构,数据结构,c语言,linux,算法)