數據結構入門


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

數據結構 = 個體 + 個體的關系

算法 = 對存儲結構的操作

算法:解題的方法和步驟

衡量算法的標准:

  1. 時間復雜度:大概程序執行要執行的次數,而非執行的時間
  2. 空間復雜度:算法執行過程中大概所占用的最大內存
  3. 難易程度
  4. 建壯性

一、指針

地址:內存單元的編號,從0開始的非負整數

指針:指針就是地址,指針變量是存放內存單元地址的變量,指針的本質是一個操作受限的非負整數

分類:

  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;
}

二、如何通過函數修改實參的值

#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;
}

三、結構體

為什么會出現結構體

為了表示一些復雜的數據,而普通的基本類型變量無法滿足要求

什么叫結構體

結構體是用戶根據實際需要,自己定義的復合數據類型

如何使用結構體

#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);
}

四、動態內存的分配和釋放

重點看代碼和注釋

#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;
}

五、跨函數使用內存

重點看代碼和注釋

#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);
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM