数据结构学习笔记(一)绪论
结构型
所谓结构型,说的通俗就是用户自己制作的数据类型。结构体是系统提供给程序员制作新的数据类型的一种机制,即可以用系统已经有的不同的基本数据类型或用户定义的结构型,组合成用户需要的复杂数据类型。
例如:
typedef struct TypeA
{
int a;
char b;
float c;
int *a;
char *b;
float *c;
}TypeA
此处的typedef的作用 是给用户定义的struct取个名字为TypeA;
指针型
对于其他类型的变量,变量里所装的东西是数据元素的内容,而指针变量内部装的是变量的地址,通过它可以找出这个变量在内存中的位置,就像一个指示方向的指针,指出了某个变量的位置,因此叫做指针型。
定义语法为在变量前加“*”,如下:
int *a;(使用指针变量a的时候应该是对a操作,而不是*a,对*a的操作如 *a = 99 实际没有任何指针的意义,有意义的操作操作应为将另一个变量的地址赋值给指针变量a(不是*a));
int b = 99;
int c
TypeA *TypeA;
1.设置指针变量a 指向变量b: a = &b,"&"为取b的地址
此时a中存放了变量b所在的地址。*a 就是取变量b的内容,此时*a 等于 99;
执行语句 c = *a 等价于执行语句 c = b;
在数据结构中,指针型用的最多的就是和结构型结合起来构造结点
结点的构造
要构造一个结点,必须先定义结点的结构类型。以链表节点和二叉树结点结构型的定义方法。
(1)链表结点的定义
链表的结点有两个域,一个是数据域,用来存放数据,一个是指针域,用来存放下一个结点的位置,如下图:
data | next |
因此链表的结构型定义如下:
typedef struct Node
{
int data; //假设存放的数据为int型
struct Node *next;//指向Node型变量的指针(此处有个疑问,struct是否可以省略? 还是因为是在定义的strcut内部定义一个struct,所以需要加上struct来指明Node是一个结构型)
}Node;
上边这个结构的名字为Node。因为组成此结构的成员中有一个是指向和自己类型相同的变量的指针,所以在内部要用自己来定义这个指针,所以写成struct Node *next。凡是结构型a内部有这样的指针b,b是用来存放和a类型相同的结构体变量的指针型,则在定义a的typedef struct语句之后都要加上a这个结构型的名字。
(2)二叉树结点的定义
包含三部分;数据域,左孩子,右孩子。
typedef struct BTNode
{
int data;
struct BTNode *lchild;
struct BTNode *rchild;
}BTNode;
(3)使用定要好的结点制作新结点
以二叉树为例:
BTNode *BT;
BT = (BTNode*)malloc(sizeof(BTNode));// p = ( *)malloc(sizeof( ));返回值为结点地址。
获取BT结点指向的结构中的数据方法:BT->data 等价于(*BT).data.
关于typedef和 #define
typedef就是用来给现有的数据类型起一个新的名字。
#define一般是用在最开始定义一个常量 : #define MAX 50
函数传参方式
(1)传递值类型
生命周期仅局限于函数体内。
void f(int x)
{
x++;
}
(2)指针类型(C#中为传递引用类型或者out型参数)
void f (int *&x)//相比值类型,在变量前加上 "*&"
{
x++;
}
(3)传递的参数为数组的特殊情况
如果将数组作为参数传入函数,函数就是对传入的数组本身进行操作,对于数组来说,没有“引用型”和“非引用型”之分。
一维数组传递方式:
void f(int x[],int n) //第一个参数中无需指明数组的长度
{ //第二个参数n是用来表明将要传入函数进行加工的数组元素的个数,
//todo //n并不是指数组的总长度。
}
二维数组传递方式:
void f(int x[][50] , int n) //二维数组中第一维的长度无需指明,但是第二维必须明确指出。
{
//todo
}
int a[10][5];
int b[10][50];
f(a); //参数错误
f(b); //参数正确