數據結構入門

定義:咱們如何把現實中大量而複雜的問題以特定的數據類型特定的存儲結構保存到主內存器中(內存),以及在此基礎上爲實現某個功能(好比查找某個元素,刪除某個元素,對全部元素進行排序)而執行的相應操做,這個相應的操做也叫算法算法

數據結構 = 個體 + 個體的關係數組

算法 = 對存儲結構的操做安全

算法:解題的方法和步驟數據結構

衡量算法的標準:函數

  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);
}
相關文章
相關標籤/搜索