数据结构入门

定义:咱们如何把现实中大量而复杂的问题以特定的数据类型特定的存储结构保存到主内存器中(内存),以及在此基础上为实现某个功能(好比查找某个元素,删除某个元素,对全部元素进行排序)而执行的相应操做,这个相应的操做也叫算法算法

数据结构 = 个体 + 个体的关系数组

算法 = 对存储结构的操做安全

算法:解题的方法和步骤数据结构

衡量算法的标准:函数

  1. 时间复杂度:大概程序执行要执行的次数,而非执行的时间
  2. 空间复杂度:算法执行过程当中大概所占用的最大内存
  3. 难易程度
  4. 建壮性

1、指针

地址:内存单元的编号,从0开始的非负整数指针

指针:指针就是地址,指针变量是存放内存单元地址的变量,指针的本质是一个操做受限的非负整数code

分类:排序

  1. 基本类型指针(重点看注释)
#include <stdio.h>

int main(void)
{
    // p是一个变量名字,int * 表示p变量只能存储int类型变量的地址
    int *p;  
    int i = 10;
    int j;

    p = &i;

    // p保存了i的地址,p指向i
    // 修改p的值不影响i的值,修改i的值不影响p的值
    // *p等于i
    
    j = *p; // 等价于 j = i

    printf("%d\n", *p);
    printf("%d\n", j);
    return 0;
}
  1. 指针与函数
#include <stdio.h>

// 不是定义了一个名字叫作 *p的形参,而是定义了一个形参,该形参的名字p,它的类型是int *
void f(int *p)
{
    *p = 100;
}


int main(void)
{
    int i = 9;
    int *p = &i;
    f(p);
    printf("%d\n", i );

    return 0;
}
  1. 指针与数组(重点看注释)
#include <stdio.h>
void show_array(int *p , int len)
{

    // p[0] == *p
    p[0] = -1;

    // p[i]就是主函数a[i]
    int i = 0;
    for (i = 0; i < len; i++)
    {
        printf("%d\n",p[i] );
    }
}


int main(void)
{
/*  
     一惟数组名是个指针常量,它存放的是一惟数组第一个元素的地址,
     它的值不能改变,一惟数组名指向的是数组的第一个元素,也就是
     a执向a[0]

     下标和指针的关系
     a[i] <==> *(a+i)
*/

    int a[5] = {1,2.3,4,5,};
    // a等价于&a[0] , &a[0]自己就是int * 类型
    show_array(a,5);

    printf("%d\n", a[0]);

    return 0;
}

全部的指针变量只占4个字节,用第一个字节的地址表示整个变量的地址

#include <stdio.h>

int main(void)
{
    double *p;
    double x = 99.9;

    // x占8个字节,1字节是8位,1字节一个地址 ,p里面存放了首地址
    p = &x;

    double arr[3] = {1.1,2.2,3.3,};
    double *q;
    double *q1;

    q = &arr[0];
    printf("%p\n", q);  // %p实际就是以十六进制输出


    q1 = &arr[1];
    printf("%p\n", q1); // 相差了8个字节


    return 0;
}

2、如何经过函数修改实参的值

#include <stdio.h>

void f(int **q);

int main(int argc, char const *argv[])
{
    int i = 9;
    int *p = &i;   // int *p , p = &i;

    printf("%p\n",p );

    f(&p);
    printf("%p\n",p );

    return 0;
}

void f(int **q)
{
    *q = (int*)0XFFFFF;
}

这样写是不安全的,可是这个理是这样的,不是修改指针的很简单,内存

#include <stdio.h>

void f(int *p);

int main(void)
{
    int i =10;
    f(&i);
    printf("%d\n", i);

    return 0;
}

void f(int *p)
{
    *p = 20;
}

3、结构体

为何会出现结构体

为了表示一些复杂的数据,而普通的基本类型变量没法知足要求字符串

什么叫结构体

结构体是用户根据实际须要,本身定义的复合数据类型

如何使用结构体

#include <stdio.h>
#include <string.h>


struct Student
{
    int sid;
    char name[200];
    int age;
}; // 分号不能省



int main(void)
{

    // 第一种方式,可是这样很麻烦

    struct Student st = {10 , "张三" ,20};
    printf("%d %s %d\n", st.sid , st.name , st.age);

    // 字符串不能直接赋值,必须调用相应的函数
    st.sid = 20;
    strcpy(st.name , "李四");
    st.age = 21;
    printf("%d %s %d\n", st.sid , st.name , st.age);



    // 第二种方式,这个最经常使用
    struct Student *pst;
    pst = &st;
    pst -> sid = 99;   // pst->sid 等价于 (*pst).sid  等价于 st.sid
    return 0;
}

pst -> sid : pst所指向的结构体中变量中的sid这个成员

注意事项

  1. 结构体变量不能加减乘除,可是能够相互赋值
  2. 普通结构体变量和结构体指针变量做为函数传参的问题
#include <stdio.h>
#include <string.h>


struct Student
{
    int sid;
    char name[200];
    int age;
};

void f(struct Student * pst);
void g(struct Student st);
void g1(struct Student * pst);

int main(void)
{
    struct Student st;
    f(&st);
    //printf("%d %s %d\n", st.sid , st.name , st.age);
    //g(st);

    g1(&st);

    return 0;
}

// 用于数据的输入
void f(struct Student * pst)
{
    (*pst).sid = 99;
    strcpy(pst -> name , "张三");
    pst -> age = 30;
}
// 用于数据的输出,可是这种方法费时间,不推荐
void g(struct Student st)
{
    printf("%d %s %d\n", st.sid , st.name , st.age);
}


// 用于数据的输出,推荐使用这种方式
void g1(struct Student * pst)
{
    printf("%d %s %d\n", pst->sid , pst->name , pst->age);
}

4、动态内存的分配和释放

重点看代码和注释

#include <stdio.h>
#include <stdlib.h>

int main(void)
{
    int a[5] = {3,9,5,6,2};

    int len;
    printf("请输入你须要的分配数组的长度:\n");
    scanf("%d" , &len);

    int * PArr = (int *)malloc(sizeof(int)*len);
    // *PArr = 3;  //相似于a[0] = 3
    // PArr[1] = 9; //相似于a[1] = 9
    // printf("%d %d\n", *PArr , PArr[1]);

    // 固然了,这个时候咱们能够把pArr看成一个普通的数组来使用
    int i;
    for (i = 0; i < len; ++i)
    {
        scanf("%d" , &PArr[i]);
    }

    int j;
    for (j = 0; j < len; ++j)
    {
        printf("%d\n", PArr[j]);
    }

    free(PArr); // 把Parr所表明的动态分配的20个字节内存释放

    return 0;
}

5、跨函数使用内存

重点看代码和注释

#include <stdio.h>
#include <stdlib.h>

struct Student
{
    int sid;
    int age;
};

struct Student * CreateStudent(void);
void ShowStudent(struct Student * ps);



int main(void)
{
    struct Student * ps;

    ps = CreateStudent();
    ShowStudent(ps);

    return 0;
}



struct Student * CreateStudent(void)
{
    // 开辟一个新空间,使用malloc函数,类型是咱们想要的类型
    struct Student * p = (struct Student * )malloc(sizeof(struct Student));
    p->sid = 88;
    p->age = 99;
    return p;
}


void ShowStudent(struct Student * pst)
{
    printf("%d %d\n", pst->sid , pst->age);
}
相关文章
相关标签/搜索