数据结构学习的预备知识

162 阅读3分钟

概述

定义

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

数据结构 = 个体 + 个体之间的关系
算法 = 对存储数据的操作

算法

解题方法和步骤

衡量算法的标准

  • 1.时间复杂度

    大概程序要执行的次数,而非执行的时间

  • 2.空间复杂度

    算法执行过程中大概所占用的最大内存

  • 3.难易程度

  • 4.健壮性


预备知识

指针

定义

地址: 内存单元的编号。从0开始的非负整数。 范围: 0 ~ FFFFFFFF(0 ~ 4G-1)

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

在数组中,数组名代表数组第一个元素的地址

#include<stdio.h>

int main() {
	int array[5] = { 1,2,3,4,5 };

	printf("%d\n",array);
	printf("%d\n",array +1);
	printf("%d\n",array +2);

	return 0;
}

结构体

定义

结构体是用户根据实际需要自己定义的符合数据类型。

结构体的模型:

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

struct  Student
{
	int sId;
	char sName[100];
};

int main() {
	struct Student s = { 1,"WangXiaoNao" };
	printf("%d	%s\n", s.sId, s.sName);

	// 第一种方式
	s.sId = 2;
	strcpy(s.sName, "wang");

	printf("%d	%s\n", s.sId, s.sName);

	// 第二种方式
	struct Student * ss = &s;
	// ss->sId;等价于(*ss).sId   而(*ss).sId等价于s.sId  所以ss->sId等价于s.sId
	ss->sId = 99; 
	printf("%d	%s\n", s.sId, s.sName);

	return 0;
}

结构体的使用方式:

struct Student s = {1,"WangXiaoNao"};
struct Student * ss = &s;

1. s.sId = 99;
2. ss->sId = 99;  // ss所指向的结构体变量中sId这个变量成员

注意事项:

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

void create(struct student * ss);
void showOne(struct student ss);
void showTwo(struct student * ss);


struct student {
	int sId;
	char sName[100];
};

int main() {

	struct student s;	// 已经为 s 分配好了内存

	create(&s);

	showOne(s);

	showTwo(&s);

	return 0;
}

void create(struct student * ss){
	ss->sId = 20;
	strcpy(ss->sName, "WangXiaoNao");
}

// 这种方式耗内存,耗时间,不推荐使用
void showOne(struct student ss) {
	printf("%d	%s\n",ss.sId,ss.sName);
}

void showTwo(struct student * ss) {
	printf("%d	%s\n",ss->sId,ss->sName);
}

malloc()动态分配内存

#include<stdio.h>
#include<malloc.h>

int main() {

	int length, i;
	printf("enter array length : ");
	scanf("%d", &length);

	int * array = (int *)malloc(sizeof(int) * length);

	/*for (i = 0; i < length; i++) {
		scanf("%d", &array[i]);
	}*/

	for (i = 0; i < length;i++) {
		scanf("%d",&*(array+i));
	}

	for (i = 0; i < length; i++) {
		printf("%d\t", *(array + i));
	}

	free(array); // 把 array 所代表的动态分配的字节的内存释放

	return 0;
}

malloc 向系统申请分配指定size个字节的内存空间。返回类型是 void*类型。void*表示未确定类型的指针。C,C++规定,void*类型可以强制转换为任何其它类型的指针

malloc()函数其实就在内存中找一片指定大小的空间,然后将这个空间的首地址范围给一个指针变量,这里的指针变量可以是一个单独的指针,也可以是一个数组的首地址,这要看malloc()函数中参数size的具体内容。我们这里malloc分配的内存空间在逻辑上连续的,而在物理上可以连续也可以不连续。对于我们程序员来说,我们关注的是逻辑上的连续,因为操作系统会帮我们安排内存分配,所以我们使用起来就可以当做是连续的。