data structure——数组、矩阵与广义表
数组:
1.两种逻辑结构
- 一维数组
dataType a[n];
- 二维数组
dataType a[m][n];
元素为一维数组的数组
2.行优先和列优先储存
这里要区分数组在定义的时候例如:int a[2][3]
中2
和3
就是又两行,有三列的意思,
而在说数组中的某一个元素是例如a[2][1]
这里的2
和1
编号,是不一样的,因为编号是从0
开始编号的。
矩阵:
1.概念
矩阵可以理解为二维数组。
2.操作
矩阵转置
1
2
3
4
5
6
7
8void trsmat(int A[][maxsize],int B[][maxsize],int m, int n) /*这里二维数组声明时省略了行的个数,
但是列数是不可以省略的*/
{
for(int i=0;i<m;i++)
for(int j=0;j<n;j++)
b[j][i]=A[i][j];
}矩阵相加
1
2
3
4
5
6void addmat(int A[][maxsize],int B[][maxsize],C[][maxsize],int m ,int n)
{
for (int i=0;i<m;i++)
for(int j=0;j<n;j++)
C[i][j]=A[i][j]+B[i][j];
}矩阵相乘
假设A[][]
和B[][]
分别为m*n
,n*k
。1
2
3
4
5
6
7
8
9
10
11
12void mutmat(int C[][maxsize],int B[][maxsize],int A[][maxsize],int m ,int n ,int k)
{
for (int i=0;i<m;++i)
for(int j=0;j<k;++j)
{
C[0][0]=0;
for(h=0;h<n;++h)
C[i][j]+=A[i][h]*B[h][j];
}
}
特殊矩阵和稀疏矩阵:
1.特殊矩阵
- 对称矩阵
- 三角阵
只需要将那些相同的元素的值加在一维数组的后面一位就可以了。 - 对角矩阵
同上
2.稀疏矩阵
稀疏矩阵有两种表示方法:
- 三元组表示法定义一个含有
1
2
3
4
5
6typedef struct
{
int val; //值
int i,j; //行标和下标
}Trimat;maxterm
个元素的稀疏矩阵:Trimat trimat[maxterm];
所以可以理解为,三元组表示法,是将稀疏矩阵以每个元素有三个分量的线性表形式将其进行存储。
当然,也可以这样存储:int trimat[maxterms+1][3];
此时:tirmat[k][0]
表示原矩阵中的元素按行优先顺序的第k
个元素的值trimat[k][1]
,tirmat[k][2]
表示第k
值在矩阵中的位置。
所以可以看出这是一个有maxterms
行3
列的数组,每行的第一列是值,第二列和第三列为这个元素的位置。
还有,我们默认的将第一行:trimat[0][0]
,trimat[0][1]
,trimat[0][2]
存储为非零元素的个数,矩阵行数,矩阵个数。
例题:
给定一个稀疏矩阵A
(float
型),其尺寸为m*n
,建立其对应的三元组存储,并通过三元组打印输出矩阵A
1 | void createtrimat(float A[][maxsize],int m ,int n, float B[][3]) //建立三元组 |
- 伪地址表示法
1.邻接表表示法
2.十字链表表示法
两种结点的结构定义:
1 | typedef struct OLNode //普通结点定义 |
例题:
给定一个稀疏矩阵A
,其尺寸是m*n
。非零元素个数是k
,建立其对应的十字链表存储结构。
1 | int creatcrossListmat(float A[][maxsize],int m,int n,int k,Crosslist &M) |
广义表:
广义表头尾链表存储结构
A( )
B(e)
C(a,(b,c,d))
D((),B,C)
E(a,E)
F(())
其中有两种结点:原子结点,广义表结点。
原子结点有两个域:标记域和数据域
广义表结点有三个域:标记域,头指针和尾指针。
当广义表非空时,第一个元素为广义表的表头,其余元素为广义表的表尾,这也是这个存储结构的名字的由来。广义表的扩展线性表存储结构
其中也有两种结点:原子结点,广义表结点。
不同的是:原子结点有三个域:标记域,头指针和尾指针。
广义表结点有三个域:标记域,头指针和尾指针。特点
广义表头尾链表存储结构类似于不带头结点的单链表存储结构,而广义表的扩展线性表存储结构类似于带头结点的单链表存储结构。
下面是例题:
1.设数组A[0,...,n-1]
的n
个元素中有多个零元素,设计一个算法,将A
数组中的所有非零元素依次移动到A
数组的前端。
1 | void movelement(int A[],int n) |
2.关于浮点型数组A[0,...,n-1]
,试设计一个实现下列运算的算法。
(1)求数组A
中的最大值。
(2)求数组中n
个数之和。
(3)求数组中n
个数的平均值。
1 | float findmax(float A[],int i ,int j) //求最大值,递归 |
3.设计一个算法,将数组A[0,...,n-1]
中所有奇数移到偶数之前。要求不增加存储空间,且时间复杂度为O(n)
。
1 | void divide(int A[],int n) |
4.设有一元素为整数的线性表L
,存放在一维数组A[0,...,n-1]
中,设计一个算法,以A[n-1]
为参考量,将该数组分为左右两个部分,其中左半部分的元素均小于等于A[n-1]
,右半部分的元素值均大于A[n-1]
,A[n-1]
则位于这两个部分之间。要求结果仍存放在数组A
中。
1 | void divide(int A[],int n) |
5.设计一个算法,对给定的一个整形m*n
矩阵A
,统计这个矩阵中具有下列特特征的元素并输出他们的坐标及数值:他们既是所在行中的最小值,又是所在列中的最小值:或者他们既是所在行中的最大值,又是所在列中的最大值。假设矩阵中元素各不相同,要求结果在处理过程中用输出语句输出。
1 | void printmin(int A[][maxsize],int m,int n) //求最小,m是行号,n是列号 |
此题是一行一行的循环,首先是由第5行的循环,然后再通过第10行的循环,找出这一行中的最小值,然后,再在第16行的循环比较,这一行的这个最小值是不是又是他所在列的最小值,如果不是就将flag
值为0,并退出,如果是,就以min,[i,minj]
的格式将其输出。求最大的值的思路一样。
6.给定稀疏矩阵A
(int
型),创建其三元组存储结构B
;查找给定元素x
是否在矩阵中。
1 | void create(int A[][maxsize],int m,int n,int B[][3]) |
7.假设稀疏矩阵A
采用三元组表示,编写一个函数,计算其转置矩阵B
,要求B
也采用三元组表示。
1 | void transpose(int A[][3],int B[][3]) |
8.假设稀疏矩阵A
和B
(两矩阵行列数对应相等)都采用三元组表示,编写一个函数,计算C=A+B
,要求C
也采用三元组表示,所有矩阵均为int
型。
1 | void add(int A[][3],int B[][3],int C[][3]) |
由稀疏矩阵而来的三元组中,其实已经存储的是稀疏矩阵中非零的元素了,切记。
9.假设稀疏矩阵A
,B
(分别为m*n
,n*k
矩阵)采用三元组表示,编写一个函数计算C=A*B
,要求C
也是采用三元组表示的稀疏矩阵。
1 | int getvalue(int D[][maxsize],int i,int j) //返回三元组中的元素对应于他在稀疏矩阵中的值 |
-..—.–..-.-./-.–..-..-.-..-/-.-.–.—…../-..—…—.-./–…-….-…-/-…-.——.-../-..—.-….–./-..—………/-.-..—–..-.-/-..-.-.-…–..-/-…-.—-.—.-/——–….–../-…-.—.-.-..-/-..—-.–…../–..—….-..-/—….-.—..-/-.—……—-/-..—…..–.-/-..–.-.–.–…/-.-…-.—.-../-..—.-….–./——–….–../-…——.–…/-..—………/-..—…-.-.-./-.-..-.-.–..-./—.–.-….-../-..—…..–.-/—.-…….–./–…-….-…-/——–….–../-….–..—–.-/—…-..–.–./–…-….-…-/—.——..-.-/-..-…..-.-..–/-.-..—–.-.-./–..–…-.—-/-..—-.–…../-.-.-..-…–../–…-….-…-/—.-.-…—–/—.–.-….-../-.—……—-/-..—…..–.-/-.—–……../-.——-….–/——–….–../-.-..—–.—-/–..–…-.—-/–..-.—–.–./-..-.-.—–.-../-..—………/-..-.-.-.——-/–…-….-…-/-…——.–…/–..–…-.—-/–..—….-..-/-..—………/—….-.—..-/-.—……—-/-.–..-..–…-/-….-….—-.-/-.-.-…–…-./–……….-./—..—.–…./-.-.—..-.-…/-..—-.–…../-.-.—..-.-…/-.-.–.——-./-..—..–..–./-..–..–….–./-..-…—..–../——–….–../-.-.—..-.-…/–…-….-…-/—.–.-….-../-.–.——-..-/-..-.—.–…-./—.—.–….-/—.—.-……/-..—.-….–./——–….–../–…-….-…-/–…-..-.-..–/-.—–……../-..-.——-..–/-..—..-.-…./——–….–../-.-..—-..-…/——.–.–..-/–…-….-…-/–…—.-.-…/-..-………..-/-..—.-….–./-..—………/-..—…-.-.-./-..—………/-..–..–..-.–./-.-..–.–….-/-.-…–..—../——–….–../-.——.-.—./-..–…–..—./-…—-.—-.–/–…-.–….-./—.—.-……/-..—-.–…../——–….–../–…-….-…-/—.—….-.–/—.—.-……/-..—-.–…../——–….–../-….–..—–.-/—…-..–.–./–.–..-.-….-/–..—….-..-/-.–..-..-.-.-./-..-.–…–..–/——–….–../-.-..–.—.-../-…——.–…/–..–…-.—-/-…-..—..-..-/—.–.-….-../-.-.-..-…–../-..—-.–…../-.-.—..-.-…/-..—………/-…–.-.—.—/—.—…—–/-.–..-.—–.-/–……….-.