线性结构
数据结构的四大逻辑结构分别是集合,线性结构,树形结构,图形结构。
四种结构的在元素间关系上的特征:
集合:元素间相互没有特定联系;
线性结构:一个元素对应一个元素
树形结构:一个元素可以对应多个元素
图形元素:多个元素之间相互有联系
线性结构又包括了数组、线性表、串、栈和队列
数组
1.一维数组
通常首地址是0,也可设置地址为1。由于数组名本身就是一个首地址,所以在输入给数组时可以不用加地址符&
例如:
有一维数组name[10],
scanf("%d",&name[0]) 与 scanf("%d",name) 等价。
2.二维数组
假设有数组 num[3] [3] = { {0,1,2} , {3,4,5} , {6,7,8} },按照概念,我们知道它的二维平铺图是这样的
0 , 1 , 2
3 , 4 , 5
6 , 7 , 8
但是计算机的内存是申请一整块的存储空间以一维数组的形式储存它,
而又能将其分为三个一维数组区处理它
将这三个一维数组记为三行 : a[0] a[1] a[2]
这里我们申请一个指向a数组的指针p
int (*p)[3] = a ;//p一个二维的数组指针,表示指向 int[3]类型的数组
但 int * p[3] 则是一个指针数组,用于存放指针,并不表示指向数组
数组指针的关系可以用这个表记忆:
*p | 一个指向数组a的指针,即二维数组的首地址 |
---|---|
*p+1 | 指向第 0 行的第1个元素 |
*(p+1) | 指向第1行 |
*((*p+1)+1) | 指向第 1 行的第1个元素 |
a + i == p + i
a[i] == p[i] == *(a+i) == *(p+i)
a[i][j] == p[i][j] == *(*a+i)+j) == *(*p+i)+j)
可以看出,i 表示 p 的第几行,j 表示 p 在该行的第几个元素。
设L是每个元素所占的存储单位,有二维数组 A [0…m - 1,0…n - 1] (即下标为0开始,m行n列)
求A [ i , j ] 的位置。
行优先:LOC( i , j ) = LOC( 0 , 0)+(n * i +j) * L
列优先:LOC( i , j ) = LOC( 0 , 0)+(m * j +i) * L
n阶对称矩阵:若n阶矩阵的元素满足以下性质,则称为对称矩阵。其中sa [ k ] 与矩阵元 a ij的关系为:
三角矩阵:以主对角线划分为上三角矩阵和下三角矩阵。上三角矩阵是指对角线以下皆为常数c或零;下三角矩阵则指对角线以上。
上三角矩阵:
下三角矩阵:
串
串与数组类似,相当于用来存放字符的数组。修改字符串时不能直接赋值,需要先申请空间然后进行储存,常用到malloc函数和strcpy函数。例如
假设字符串A = “abc”, B = “defgh”,要将B加到A里
char * A = NULL;
char * B = NULL;
char * C = NULL;
A = (char*)malloc(sizeof(char)*3);
B = (char*)malloc(sizeof(char)*4);
strcpy(A,"abc");
strcpy(B,"defg");
C = (*char)realloc(sizeof(char)*(lengthA+lengthB));
C = strcat(A,B);
则称A,B为C的子串,C为A,B的主串
广义表
广义表是非线性的数据结构,表中的元素可以是一个原子也可是一个广义表,而表尾必是一个广义表。例如
L = (a,b),则head(L) = a,tail(L) = (b)
K = (a,(b,c)),则head(K) = a,tail(K) = ( (b,c) )
J = ( (a,b),(c,d),(e,f,g) ),则head(J) = (a,b),tail(J) = ( (c,d),(e,f,g) )
H = ( a,( b,( c,(d,e) ) ) ),head(H) = a ,tail(H) = ( (b,(c,(d,e) ) ) )
广义表的长度按最外层括号里的逗号决定,如 L的长度为2 , K的长度为2 , J的长度为3,H的长度为2
广义表的深度按括号的最大层数决定,如 L的深度为1,K的深度为2, J的深度为2, H的深度为4