目录
1. 数组基础
一维、二维数组
二维数组:行优先、列优先
例题:二维数组A[6][10],每个数组元素占4个存储单元,按行优先,A[3][5]的存储地址是1000,求A[0][0]的存储地址?
3*10 + 5 = 35(个存储单元)
1000 - 35 * 4 = 860
1.1 定义初始化 + 赋值 + 求长度
初始化 参见:https://blog.csdn.net/qq_40893824/article/details/105874127
赋值 + 求长度 参见:https://blog.csdn.net/qq_40893824/article/details/105753917
2. 矩阵压缩存储
2.1 矩阵
转置、相加、相乘
2.2 特殊矩阵 和 稀疏矩阵
2.2.1 特殊矩阵:对称阵 、 三角阵 、 对角阵
(1) 对称阵 (下三角)
(2) 三角阵(下三角)
(3) 对角阵
2.2.2 稀疏阵
顺序存储:1 三元组,2 伪地址;
链式:1 邻接表,2 十字链表
2.2.2.1 三元组
#include<bits/stdc++.h>
using namespace std;
typedef struct
{
int val;
int i, j;
}Trimat;
//在主函数中定义 Trimat trimat[m + 1] ; m的意思:m个非0元素,1是第一行存储非0元素个数 和 几维矩阵
// 可简单直接定义二维数组为三元组 int trimat[m + 1][3];
// float类型的元素则:float trimat[m + 1][3];
// 下标:(int) trimat[k][1]; 和 (int) trimat[k][2];
int main()
{
return 0;
}
矩阵 用 三元组存储:
代码:
#include<bits/stdc++.h>
#define max 100
using namespace std;
void print(float a[][4], int m, int n)
{
cout << "输出数组:" << endl;
int i, j;
for(i = 0; i < m; i++)
{
for(j = 0; j < n; j++)
{
cout << a[i][j] << " ";
}
cout << endl;
}
cout << endl;
}
void print2(float trimat[][3])
{
int i, j, k = 1;
for(i = 0; i < trimat[0][1]; i++)
{
for(j = 0; j < trimat[0][2]; j++)
{
if(i == (int)trimat[k][1] && j == (int)trimat[k][2])
{
cout << trimat[k][0] << " ";
k++;
}
else
cout << "0" << " ";
}
cout << endl;
}
}
void creat(float trimat[][3], float a[][4], int m, int n)
{
int i, j, k = 1;
for(i = 0; i < m; i++)
{
for(j = 0; j < n ; j++)
{
if(a[i][j] != 0)
{
trimat[k][0] = a[i][j];
trimat[k][1] = i;
trimat[k][2] = j;
k++;
}
}
}
trimat[0][0] = k-1;
trimat[0][1] = m;
trimat[0][2] = n;
cout << "三元组创建成功!" <<endl <<endl;
}
int main()
{
float a[4][4] = {{0,0,0,1},{0,0,3,2},{1},{0,1}};
print(a, 4, 4);
float trimat[max][3];
creat(trimat, a , 4, 4);
cout << "三元组输出:" <<endl;
print2(trimat);
return 0;
}
2.2.2.2 伪地址
元素值 + 地址
其中 地址 = n(i - 1) + j,可按行优先 或 列优先
2.2.2.3 邻接表
2.2.2.4 十字链表
结点:
row 行号
col 列号
val 值
down 下指针
right 右指针
十字链表:
左上角结点是 头结点,其它的是 普通结点
代码
思路:
- 初始化头结点
- 分配空间
- 辅助链表(下面的,指针指向右)
注意结点结构体 定义时,各参数的含义!
#include<bits/stdc++.h>
#define max 100
using namespace std;
typedef struct QNode // 普通结点
{
int row, col; // 行号、列号
float val; // 值
struct QNode *down, *right; //指向 下 和 右 的指针
}*Link, QNode;
typedef struct // 头结点
{
QNode *rhead, *chead; //下边的(指针指向右)、右边的(指针指向下)
int m, n, k; // 行、列数 及 非零结点数
}crossList;
void print(float a[][4], int m, int n)
{
cout << "输出数组:" << endl;
int i, j;
for(i = 0; i < m; i++)
{
for(j = 0; j < n; j++)
{
cout << a[i][j] << " ";
}
cout << endl;
}
cout << endl;
}
int count(float a[][4],int m, int n)
{
int i, j, c = 0;
for(i = 0; i < m; i++ )
{
for(j = 0; j < n; j++)
{
if(a[i][j]!=0)
c++;
}
}
return c;
}
void creat(float a[][4], int m, int n, int k, crossList &M) // 矩阵:m x n
{
int i, j;
// 初始化头结点
if(M.chead)
free(M.chead);
if(M.rhead)
free(M.rhead);
M.m = m;
M.n = n;
M.k = k;
// 分配空间 并 置空
M.rhead = (QNode *)calloc(m, sizeof(QNode));
M.chead = (QNode *)calloc(n, sizeof(QNode));
//辅助链表 右边横着的 指针向下
QNode *temp[max];
for(i = 0; i < n; i++)
temp[i] = &(M.chead[i]);
for(i = 0; i < m; i++)
{
QNode *c = &(M.rhead[i]);
for(j = 0; j < n ; j++)
{
if(a[i][j]!=0)
{
QNode *p = (QNode *)calloc(1,sizeof(QNode));
p->row = i;
p->col = j;
p->val = a[i][j];
p->down = p->right = NULL;
c->right = p;
c = p;
temp[j]->down = p;
temp[j] = p;
}
}
}
cout << "十字链表创建成功!" << endl << endl;
}
void print2(crossList M)
{
cout << "输出十字链表:" << endl;
int i, j ,r;
QNode *p = (QNode* )malloc(sizeof(QNode));
for(i = 0; i < M.m; i++)
{
p = M.rhead[i].right;
for(j = 0 ; j < M.n; j++)
{
if((int)p->col != j)
cout << "0" << " ";
else
{
cout << p->val << " ";
if(p->right)
p = p->right;
}
}
cout << endl;
}
}
int main()
{
float a[4][4] = {{0,0,0,1},{0,0,3,2},{1},{0,1}};
print(a, 4, 4);
int length = count(a, 4, 4);
crossList M;
creat(a, 4, 4, length, M);
print2(M);
return 0;
}
3. 广义表
长度 = 最上层元素个数
深度 = 括号的最大层数
A = (),空表,长度 = 0,深度 = 1
B = (d, e),元素全是原子,长度 = 2,深度 = 1
C =(b, (c, d)),1个原子 + 1个广义表,长度 = 2,深度 = 2
D = (B, C),2个广义表,长度 = 2,深度 = 3
E = (a, E),1个原子 + 它本身,长度2,深度无穷
头尾链表:(原子结点 + 广义表结点)
原子结点 = 标记域 + 数据域
广义表结点 = 标记域 + 头指针域 + 尾指针域
扩展线性表:(原子结点 + 广义表结点)
原子结点 = 标记域 + 数据域 + 尾指针
广义表结点 = 标记域 + 头指针域 + 尾指针域
表头(Head),表尾(Tail)
取表头 不叫括号
取表尾 加括号