数据结构笔记整理和思考--零碎(1)

1.      数据结构主要是研究现实中大而复杂的问题如何以特定的数据类型和特定的存储结构保存在主存储器(内存)中(简而言之,在内存中,个体的如何存储和个体之间关系如何存储)。而如何对这些数据进行操作,就叫做算法。

2.      数组:由于是连续存储,故往往要开辟新的内存以保证连续,那么对已有空闲内存的利用率很低。

线性表:离散存储,可以将内存的间隙(或者说内存碎片)都利用起来。可是在实际使用的过程中,例如开发人事管理系统时,线性表表现不了“上级和下级”关系。

树:可以表现现实中有阶级关系的问题,如公司人事管理系统

图:一般在交通规划中使用,如怎样保证任意两个站点距离市中心的距离一致,再如百度地图中,计算任意两个点之间的距离等。

3.      衡量算法的标准:时间复杂度(最关键的步骤的执行次数),空间复杂度,难易程度,健壮性(即:能处理输入的恶意非法数据,不会报错生病)。

4.      栈内存和堆内存的区别是:内存的分配方式的不同(前者是通过出栈压栈的方式分配),而不是两个内存区域。

5.      CPU 直接可以操作的最大存储空间是内存。内存,可以形象地划分为一个个的小格子,每一个格子都有唯一的编号(0 —— 4G-1),这就是地址,也就是指针。也就是说指针就是一个内存单元地址,或者说 一个操作有限(加减乘除有限)的非负整数。而指针标量则是存放指针的变量。

6.      存储单元一般应具有存储数据和读写数据的功能,以8位二进制作为一个存储单元,也就是一个字节。每个单元有一个地址,是一个整数编码,可以表示为二进制整数。程序中的变量和主存储器的存储单元相对应:变量的名字对应着存储单元的地址,变量内容对应着单元所存储的数据。存储地址一般用十六进制数表示,而每一个存储器地址中又存放着一组二进制(或十六进制)表示的数,通常称为该地址的内容。

7.      C语言指针辨析:

操作一个变量,就是间接地操作这个变量存放的内容

int  i = 10;

i ++;                //i存放的内容加1

Int  j=i;  //i存放的内容赋给j;

 

*P : 代表 指针变量p所存放的内容

int  * p ;  (p 是指针变量名,也是一个变量,对应着一个内存单元地址,但存放的内容是地址)

int  * q;   (p)

int   i=10;  (i 是变量名,对应着一个内存单元地址,也就是说,i是一个地址(或指针),存放的内容是整形数据)

int   j;       (j i)

 

p = &i(将变量i的地址 赋给 p  , 那么p的内容*p就是i对应的内存单元地址,这样 *p  就等价于 i ,  可以直接将*p看成i来用)

j = *p;   (由上面,*p 可以看成 i  ,  在此就是 j = i)

q = p;   (p 存放的地址 赋给 指针变量,这样的话,*q 就是 &i ,那么*q 就是i )

8.      一维数组 int[] arr = {1,2,3,4}

a)       一维数组名arr 是一个指针常量,存放的是arr[0]的地址(不是内容),存放的是不能修改的。

b)       由于数组的物理地址是连续的,所以arr[3] == *(a+3)

问题:常量 和 变量 在内存中的区别是什么?

9.    有人说,java中没有指针的概念,这的确是,因为java编程中我们的确无法像C语言这样获取到一个变量的地址;可是java中却有C语言中的指针变量的概念,就是对象或数组的引用!!  
但是C中的指针要比java的对象引用变量灵活的多,例如java中一个变量我们无法获取其地址,只能获取其内容,然而,C中,通过 &变量名  就可以获取这个变量的地址。

10.   任何类型的指针变量都是占用4个字节。任何类型的指针变量都是只存放着指针的第一个或最后一个字节而已。

11.    C语言中,对于一个结构体struct Student st{int id,String name,int money},函数f(struct Student * pst)g(struct Student st),使用后面两个函数来打印结构体的值时,后者会耗更多的内存和时间的,因为前者是将结构体st的内存地址发送给形参,而后者则是将st的内容发送给形参,很明显后者得发送很大的数据。这是C语言中一些内存优化细节方面的现象了。

对比java中的类作为参数传递:假设有class Student{ int id;String name;int money }和函数f(Student st),有一下常见的编程习惯:

1, fnew Student());

2, Student st = new Student();

fst;

         这两种方式就没有C语言中的那么复杂,因为new Student() 返回的就只是开辟的内存空间的首地址,不会是这个对象的内容,所以这两种方式不会像上面的C语言的例子中的“传递地址”和“传递内容”的区别。

 

12.    malloc(int a) :返回类型是 void* 类型。void* 表示未确定类型的指针。C,C++规定,void* 类型可以强制转换为任何其它类型的指针。即,动态开辟a个字节的内存空间,然后将第一个字节的地址返回。注意的是,这个新的内存空间是不属于任何类型的,所以我们可以自己将其强制转化成某种数据类型的内存空间,例如

a)     int * p = (int *) malloc(int a);// 整型存储单元,并将这128个连续的整型存储单元的首地址存储到指针变量p中,所以其实是int数组。

b)    String * p = (String *) malloc(int a); //其实是String数组

//////////反思javanew//////////

Java中我们经常使用new来开辟堆内存,其实底层实现是:

         A a = new A();

à    A a = (A)malloc(sizeOf(A));

13.    数组与指针的关系:我们知道int[] arr =new int[10] 是指在内存中开辟10*4个字节的连续的整型存储单元,然后将这个空间的第一个字节的内存单元地址赋给指针arr (即arr = &arr[0] )。

int * parr = (int *)malloc(10*4);其实和上面的过程一样。应该说数组的底层实现就是后者。

14.   内存泄漏也称作“存储渗漏”,用动态存储分配函数动态开辟的空间,在使用完毕后未释放,结果导致一直占据该内存单元。直到程序结束。其实说白了就是该内存空间使用完毕之后未回收.

15.    C语言中我们可以自己动态分配内存(malloc(int)),也可以自己释放内存(free(指针变量)),可是在大型而复杂的项目之中,很多时候我们由于种种原因没有free内存(例如忘了),这样子的话,内存就会占用得越来越多,所以系统就会越来越慢。一个例子就是我们的OS,其内核都是C语言写的,当用得久的话,我们就会明显感觉卡了。这也是为什么我们说CC++语言不安全的原因容易内存泄露,而java由于独特的GC机制,所以内存都自动回收了。从这个点来说,java的开发的系统又比C++开发的好了,至少没那么容易奔溃,哈哈。

16.    我们将现实世界中的业务数据存放进内存中时,往往有两种方式:线性结构(数组,链表等)和非线性结构(树和图)。

所谓线性结构:就是所有结点可以通过一条线串起来。

线性结构又分为两类:连续存储(数组)和离散存储(链表)

17.    typedef 数据类型 别名 ----->  常用于 为名字过长的结构体(指针变量) 取别名(一般用大写)

typedef struct Student {

         int age; String name

}  STU;    àà  就是说为结构体Student  起一个别名 STU

typedef struct Student {

         int age; String name

} * PSTU;    àà  就是说为结构体Student的指针变量类型  起一个别名 PSTU


来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/29900383/viewspace-1460771/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/29900383/viewspace-1460771/

你可能感兴趣的:(数据结构笔记整理和思考--零碎(1))