一篇文章让你彻底理解数组及其扩展的数据结构,快速转置算法等,千字超详细总结!

简介: 数组本章主要介绍数组基本概念及其扩展,二维数组的特殊矩阵:对称矩阵、三角矩阵、稀疏矩阵、十字链表等存储解耦;然后介绍并实现了稀疏矩阵的快速转置算法。可以转载,但请声明源链接:文章源链接justin3go.com(有些latex公式某些平台不能渲染可查看这个网站)

数组

本章主要介绍数组基本概念及其扩展,二维数组的特殊矩阵:对称矩阵、三角矩阵、稀疏矩阵、十字链表等存储解耦;然后介绍并实现了稀疏矩阵的快速转置算法。

可以转载,但请声明源链接:文章源链接justin3go.com(有些latex公式某些平台不能渲染可查看这个网站)

数组



特点:

  • 结构固定
  • 每一个维度上的元素同构

数组运算:

  • 给定位置,存取相应数据元素。
  • 给定位置,修改数据元素的值。
  • 数组一般不做添加或删除操作。

数组顺序存储:

  • 以行序为主序。

Loc(a_{ij}) = Loc(a_{00}) + (i\times n + j)\times L\

\

  • 以列序为主序。

Loc(a_{ij}) = Loc(a_{00}) + (j\times m + i)\times L\

\

特殊矩阵


对称矩阵

n = \begin{cases} & \text i(i+1)/2+j, i>=j \\ & \text j(j+1)/2+i, i<j \end{cases}\

\

image.png

三角矩阵

image.pngn = \begin{cases} & \text i(i+1)/2 + j, i>=j \\ & \text n(n+1)2, i<j \end{cases}\

\

三对角矩阵



image.png

(按行主序为例)

  • 总长度:3n-2
  • 已知k(0<=k<=3n-3)
  • i = (k+1)/3
  • j = (k+1)%3+i-1
  • image.png

稀疏矩阵



定义

image.png

  • 非零元个数<<零元个数
  • 分布没有规律
  • 对矩阵M:
  • density = M中非零元总数/M的元素总数。
  • density<=5%时,则称M为稀疏矩阵。
  • density称为M的稠密度。

压缩存储

  • 三元组法
  • 存储非零元的行、列下标及其值。
  • 存储矩阵的行、列维数。
  • 三元组:{0,1,12},{0,2,9},{3,1,-3}······
  • 行列式维数:(6,7)
  • 非零元个数:8


image.png

快速转置

image.png

一般的矩阵转置:

for(col = 0; col < n; col++){
    for(row = 0; row < m; row++){
        n[col][row] = m[row][col];
    }
}
//时间复杂度:T(n) = O(mxn)


快速转置:

  • 按M中三元组次序转置,转置结果放入N中恰当位置。
  • 确定M中每一列第一个非零元在N中位置。
  • 为确定这些位置,应先计算M中每一列中非零元个数。
  • 设两个辅助数组
  • num[col]:表示M中第col列中非零元个数。
  • cpot[col]:指示M中第col列第一个非零元在N中位置。
  • 显然有
  • cpot[1] = 1
  • cpot[col] = cpot[col-1] + num[col-1]; (2<=col<=M[0])

image.png

image.png

准备:

#include<iostream>
#include<vector>
#include<cstring>
using namespace std;
int num[5][5] = {
    {1,1,1,1,1},
    {0,0,0,1,0},
    {0,0,1,0,0},
    {0,1,0,0,0},
    {1,1,1,1,1},
};


链式存储:

struct elements
{
    int col;
    int row;
    int val;
    elements* next;
    elements(int col, int row, int val):
    col(col),row(row),val(val),next(NULL){}
};
//这里偷点懒就不把长度传进来了O(∩_∩),数组定义的全局变量
void num2elements(elements* head){
    elements* temp = NULL;
    for(int i = 4; i >= 0; i--){
        for(int j = 4; j >= 0; j--){
            if(num[i][j] != 0){
                temp = new elements(i, j, num[i][j]);
                temp->next = head->next;
                head->next = temp;
            }
        }
    }
}


顺式存储:

vector<vector<int>> elements;
vector<int> temp;
void num2elements(){//转换3元组
    temp.push_back(5);
    temp.push_back(5);
    temp.push_back(13);
    elements.push_back(temp);
    temp.clear();
    for(int i = 0; i < 5; i++){
        for(int j = 0; j < 5; j++){
            if(num[i][j] != 0){
                temp.push_back(i);
                temp.push_back(j);
                temp.push_back(num[i][j]);
                elements.push_back(temp);
                temp.clear();
            }
        }
    }
}


转置操作:

int count[5];
int cpot[5];
int result[14][3];//转置后的结果;
void trans(){
    //init count
    for(int i = 0; i < elements.size(); i++){
        count[elements[i][1]]++;
    }
    //init cpot
    int sum = 0;
    for(int i = 0; i < 5; i++){
        cpot[i] = sum;
        sum += count[i];
    }
    int index = 0;
    for(int i = 1; i < 14; i++){
        index = ++cpot[elements[i][1]];
        result[index][0] = elements[i][1];
        result[index][1] = elements[i][0];
        result[index][2] = elements[i][2];
    }
    //把行列及非零个数进行赋值
    result[0][0] = elements[0][1];
    result[0][1] = elements[0][0];
    result[0][2] = elements[0][2];
}
int T_num[5][5];
void print_result(){
    memset(T_num, 0, sizeof(T_num));
    for(int i = 1; i < 14; i++){
        T_num[result[i][0]][result[i][1]] = result[i][2];
    }
    for(int i = 0; i < 5; i++){
        for(int j = 0;j < 5; j++){
            cout << T_num[i][j] << ", ";
        }
        cout << endl;
    }
}

主函数:

int main(){
    //elements* head = new elements(5, 5, 13);
    //num2elements(head);
    num2elements();
    for(int i = 0; i < elements.size(); i++){
        for(int j = 0; j < 3; j++){
            cout << elements[i][j] << ", ";
        }
        cout << endl;
    }
    cout << "*************************" << endl;
    trans();
    for(int i = 0; i < 14; i++){
        for(int j = 0; j < 3; j++){
            cout << result[i][j] << ", ";
        }
        cout << endl;
    }
    cout << "*************************" << endl;
    print_result();
    return 0;
}


结果:

/*
5, 5, 13, 
0, 0, 1,
0, 1, 1,
0, 2, 1,
0, 3, 1,
0, 4, 1,
1, 3, 1,
2, 2, 1,
3, 1, 1,
4, 0, 1,
4, 1, 1,
4, 2, 1,
4, 3, 1,
4, 4, 1, 
*************************
5, 5, 13,
0, 0, 1,
0, 4, 1,
1, 0, 1,
1, 3, 1,
1, 4, 1,
2, 0, 1,
2, 2, 1,
2, 4, 1,
3, 0, 1,
3, 1, 1,
3, 4, 1,
4, 0, 1,
4, 4, 1,
*/


十字链表


  • 对顺序存储的三元组表,移动元素的时间开销大
  • 为维护行主序、列有序,可能产生更多开销

十字链表是稀疏矩阵的另一种存储策略

  • 每个非零元为一个结点,每个结点含五个域。
  • 其中,行域i、列域j、值域v分别表示非零元素的行下标、列下标和值。
  • 向右域right链接同一行中下一个非零元素。
  • 向下域down链接同一列中下一个非零元素。
  • 十字链表存储需要额外的指针域、行、列指针
  • 一般的,当非零元的数不超过总元素个数的20%,适用十字链表存储。


image.png

image.png

目录
相关文章
|
23天前
|
算法 数据处理 C语言
C语言中的位运算技巧,涵盖基本概念、应用场景、实用技巧及示例代码,并讨论了位运算的性能优势及其与其他数据结构和算法的结合
本文深入解析了C语言中的位运算技巧,涵盖基本概念、应用场景、实用技巧及示例代码,并讨论了位运算的性能优势及其与其他数据结构和算法的结合,旨在帮助读者掌握这一高效的数据处理方法。
34 1
|
2月前
|
存储 人工智能 算法
数据结构与算法细节篇之最短路径问题:Dijkstra和Floyd算法详细描述,java语言实现。
这篇文章详细介绍了Dijkstra和Floyd算法,这两种算法分别用于解决单源和多源最短路径问题,并且提供了Java语言的实现代码。
92 3
数据结构与算法细节篇之最短路径问题:Dijkstra和Floyd算法详细描述,java语言实现。
|
24天前
|
存储 算法 搜索推荐
Python 中数据结构和算法的关系
数据结构是算法的载体,算法是对数据结构的操作和运用。它们共同构成了计算机程序的核心,对于提高程序的质量和性能具有至关重要的作用
|
24天前
|
数据采集 存储 算法
Python 中的数据结构和算法优化策略
Python中的数据结构和算法如何进行优化?
|
1月前
|
算法
数据结构之路由表查找算法(深度优先搜索和宽度优先搜索)
在网络通信中,路由表用于指导数据包的传输路径。本文介绍了两种常用的路由表查找算法——深度优先算法(DFS)和宽度优先算法(BFS)。DFS使用栈实现,适合路径问题;BFS使用队列,保证找到最短路径。两者均能有效查找路由信息,但适用场景不同,需根据具体需求选择。文中还提供了这两种算法的核心代码及测试结果,验证了算法的有效性。
97 23
|
1月前
|
算法
数据结构之蜜蜂算法
蜜蜂算法是一种受蜜蜂觅食行为启发的优化算法,通过模拟蜜蜂的群体智能来解决优化问题。本文介绍了蜜蜂算法的基本原理、数据结构设计、核心代码实现及算法优缺点。算法通过迭代更新蜜蜂位置,逐步优化适应度,最终找到问题的最优解。代码实现了单链表结构,用于管理蜜蜂节点,并通过适应度计算、节点移动等操作实现算法的核心功能。蜜蜂算法具有全局寻优能力强、参数设置简单等优点,但也存在对初始化参数敏感、计算复杂度高等缺点。
60 20
|
25天前
|
存储 缓存 算法
在C语言中,数据结构是构建高效程序的基石。本文探讨了数组、链表、栈、队列、树和图等常见数据结构的特点、应用及实现方式
在C语言中,数据结构是构建高效程序的基石。本文探讨了数组、链表、栈、队列、树和图等常见数据结构的特点、应用及实现方式,强调了合理选择数据结构的重要性,并通过案例分析展示了其在实际项目中的应用,旨在帮助读者提升编程能力。
46 5
|
1月前
|
存储 人工智能 算法
数据结构实验之C 语言的函数数组指针结构体知识
本实验旨在复习C语言中的函数、数组、指针、结构体与共用体等核心概念,并通过具体编程任务加深理解。任务包括输出100以内所有素数、逆序排列一维数组、查找二维数组中的鞍点、利用指针输出二维数组元素,以及使用结构体和共用体处理教师与学生信息。每个任务不仅强化了基本语法的应用,还涉及到了算法逻辑的设计与优化。实验结果显示,学生能够有效掌握并运用这些知识完成指定任务。
53 4
|
1月前
|
机器学习/深度学习 算法 C++
数据结构之鲸鱼算法
鲸鱼算法(Whale Optimization Algorithm,WOA)是由伊朗研究员Seyedali Mirjalili于2016年提出的一种基于群体智能的全局优化算法,灵感源自鲸鱼捕食时的群体协作行为。该算法通过模拟鲸鱼的围捕猎物和喷出气泡网的行为,结合全局搜索和局部搜索策略,有效解决了复杂问题的优化需求。其应用广泛,涵盖函数优化、机器学习、图像处理等领域。鲸鱼算法以其简单直观的特点,成为初学者友好型的优化工具,但同时也存在参数敏感、可能陷入局部最优等问题。提供的C++代码示例展示了算法的基本实现和运行过程。
50 0
|
2月前
|
机器学习/深度学习 存储 缓存
数据结构与算法学习十:排序算法介绍、时间频度、时间复杂度、常用时间复杂度介绍
文章主要介绍了排序算法的分类、时间复杂度的概念和计算方法,以及常见的时间复杂度级别,并简单提及了空间复杂度。
41 1
数据结构与算法学习十:排序算法介绍、时间频度、时间复杂度、常用时间复杂度介绍