数据结构 - 数组

数组与线性表的差异

我们以前应该学习过数组,数组与线性表的区别与联系呢?

它们的相同之处:

(1)它们的相同之处,它们都是若干个相同数据类型的数据元素a0,a1,a2,…,an-1构成的有限序列

它们的不同之处:

(1)数组要求其元素占用一块地址连续的内存单元空间,而线性表无此要求

(2)线性表的元素是逻辑意义上不可再分的元素,而数组中的每个元素还可以是一个数组

(3)数组的操作主要是向某个下标的数组元素中存放数据和取某个下标的数组元素,这与线性表的插入和删除操作不同

数组的定义

数组的逻辑定义: n(n>1)维数组是一个向量,它的每个元素是n-1维数组,且具有相同的上限和下限。

n维数组的元素个数

设n维数组为:

A[c1..d1, c2..d2, … , cn..dn ]

其元素个数为:

- 数组逻辑上是线性结构的推广

- 数组是以线性表为元素的线性结构,而且元素的结构相同

- 数组可以看作是下标和值的偶对的集合

- 数组是一种逻辑结构

数组的操作 :数组一般不做插入和删除操作(效率较低)

对于数组的操作一般只有两类:

(1)给定一组下标,存取相应的数据元素

(2)给定一组下标,修改相应的数据元素的值

数组的顺序存储

(1)一维数组(n个元素)中任一元素ai的内存单元地址

   LOC(ai)=LOC(a0)+i*k

  

(2)一个m行n列的二维数组

  LOC(aij)=LOC(a00)+(i*n+j)*k

  

注意:C语言中数组元素采用行主序的存放方法,即行优先顺序。

顺序存储时按行序和列序的约定

以“行序为主序”的存储映象

二维数组中任一元素a[i][j] 的存储位置

LOC(i,j) = LOC(0,0) + (b2×i+j)×L

其中:LOC(0,0) 称为基地址或基址

设二维数组A[c1..d1][c2..d2] 其中c1、c2和d1、d2分别为二维数组A的下标的下界和上界,每个数组元素占L个存储单元,设第一个元素A[c1][c2]的存储位置为LOC(c1,c2),则该二维数组中任一元素A[i][j] ( c1≤i≤d1,c2≤j≤d2)的存储位置可由下式确定:

在C语言中,下标从零开始,即:A[0..d1][0..d2] ,则数组元素A[i][j]的存>储位置是 :

LOC(i,j)=LOC(0,0)+(i*(d2+1)+j)*L

n维数组的元素存储位置

N维数组中,数组元素存储位置的确定:

公式如下:

三维数组的表示方法

LOC(i,j,k) = LOC(l1,l2,l3)+

[ (i-l1) * (u2-l2) * (u3-l3) +( j-l2) * (u3-l3) + (k-l3) ]* L

若l1=l2=l3 = 0;

LOC(i,j,k) = LOC(0,0,0) + ( i * u2* u3 + j * u3 +k )*L

矩阵的压缩存储

压缩存储思想

当矩阵的阶数较高,而且矩阵中的一些元素有特殊的性质时,可以采用节省空间的存储办法(压缩存储)

特殊矩阵

值相同的元素或非零元素分布有一定的规律

(1) 对称矩阵

若n 阶方阵 A 中的元素满足下述性质:

aij=aji 1≤i , j≤n

则称A为n阶对称矩阵。

分析:

对于对称矩阵来说,n2个元素可以压缩到n(n+1)/2个空间中

以行序为主序将其下三角(包括对角线)中的元素

存储到一个向量B[n(n+1)/2]中:

对称矩阵特点:

向量B[k]和矩阵中的元素aij之间存在着一一对应关系:

下面按下标从从0开始讨论

下标变换公式

向量B[k]和矩阵中的元素aij之间的关系:由i和j推导k:

(2) 三角矩阵

    什么是三角矩阵呢?

三角矩阵 :

下三角矩阵是指矩阵的上三角(不包括对角线)中的元素均为零或常数的n阶方阵

注意:下三角矩阵存储公式和对称矩阵存储主对角线以下元素的公式基本相同,只需额外再增加一个存储常数或零的存储空间即可

(3)对角矩阵

三对角矩阵:共3n-2个非零元素,存入B[3n-2]中,元素在一维数组B

中的下标k和元素在矩阵中的下标i和j的对应关系为:

k = 3(i-1)-1(主对角线左下角,即i=j+1)

k = 3(i-1) (主对角线上,即i=j)

k = 3(i-1)+1(主对角线上,即i=j-1)

由以上三式,得

k=2(i-1)+(j-1) (1 ≤ i,j ≤ n; 0 ≤ k ≤ 3n-1)

稀疏矩阵

非零元素少且分布无规律

稀疏因子:

假设 m 行 n 列的矩阵含 t 个非零元素,则

稀疏因子为δ = t/(m*n) <= 0.05

为什么使用稀疏矩阵?

以常规方法,即以二维数组表示高阶的稀疏矩阵时产生的问题:

(1)零值元素占了很大空间

(2)计算中进行了很多和零值的运算,遇除法,还需判别除数是否为零

解决问题的原则:

(1)尽可能少存或不存零值元素

(2)尽可能减少没有实际意义的运算

(3)操作方便。即:能尽可能快地找到与下标值(i,j)对应的元素,能尽可能快地找到同一行或同一列的非零值元

注意:压缩存储时,对零元素不分配存储空间,只存储稀疏矩阵中的非零元

顺序存储结构 — 三元组表

三元组顺序表

三元组类型

#define  MAXSIZE  12500
 typedef struct {
     int   i,  j;   //该非零元的行下标和列下标
     ElemType  e;   // 该非零元的值
 } Triple;

稀疏矩阵类型

typedef struct {
     Triple  data[MAXSIZE + 1];
      int     mu, nu, tu;
} TSMatrix;  

链式存储结构 — 十字链表

十字链表中非零元结点的结构:

十字链表的结构类型

typedef    struct   OLNode {
  int i , j;
   ElemType e;
   struct OLNode *down, *right;
 }OLNode;*OLink;

typedef   struct
{
   OLink   *rhead,  *chead ;  //行、列链表头指针
   int     mu,   nu ,  tu  ;
} CrossList;

时间: 2024-10-24 02:15:38

数据结构 - 数组的相关文章

【C/C++学院】0828-数组与指针/内存分配/数据结构数组接口与封装

[送给在路上的程序员] 对于一个开发者而言,能够胜任系统中任意一个模块的开发是其核心价值的体现. 对于一个架构师而言,掌握各种语言的优势并可以运用到系统中,由此简化系统的开发,是其架构生涯的第一步. 对于一个开发团队而言,能在短期内开发出用户满意的软件系统是起核心竞争力的体现. 每一个程序员都不能固步自封,要多接触新的行业,新的技术领域,突破自我. 数组与指针 #include<stdio.h> #include<stdlib.h> void main1() { int a[10]

数据结构-数组中出现次数超过一半的数字

题目:数字中有一个数字出现的次数超过数组长度的一半,请找出这个数字.例如输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}.由于数字2在数组中出现了5次,超过数组长度的一半,因此输出2. 分析:首先进行排序,因为大于一半,所以说经过排序之后的数组,如有次数大于的话说明那个数肯定是数组中间的那个数. #include <iostream> using namespace std; void QickSort(int *a,int n,int low,int high){ int i=l

java数据结构 - 数组使用的代码

在研发过程中,将开发过程比较好的内容珍藏起来,下面内容段是关于java数据结构 - 数组使用的内容,希望能对大伙有较大用. public class Array { private int[]Array; private int ArraySize; private int ArrayLength; private void GetArray(){ Array = new int[ArraySize]; if(Array == null) System.out.println("Memory A

算法整理篇之:数据结构 | 数组(1)

数组,是最基础的数据结构,因为其所代表的是一段连续序列(如果按照C++中的定义),或者从广义上来讲的一个集合. 结构特点: 1)索引(Index),又叫下标: 一般地,我们可以借鉴下标的思想,对数据进行标号,从而组织成为序列,最大的好处就是能够保证元素的唯一性,如同数据库的Primary Key. 这与”寻址“,”父亲表示法“,”指针“的思想是同出一辙的. 2)值(Value),又叫元素. 直接结果,当然,这个直接结果也可能就是一个索引,在算法中,常见形如:”a[[i+j]]“. 思想变种: 当

[数据结构] 数组与链表的优缺点和区别

概述 数组 是将元素在内存中连续存放,由于每个元素占用内存相同,可以通过下标迅速访问数组中任何元素.但是如果要在数组中增加一个元素,需要移动大量元素,在内存中空出一个元素的空间,然后将要增加的元素放在其中.同样的道理,如果想删除一个元素,同样需要移动大量元素去填掉被移动的元素.如果应用需要快速访问数据,很少插入和删除元素,就应该用数组. 链表 中的元素在内存中不是顺序存储的,而是通过存在元素中的指针联系到一起,每个结点包括两个部分:一个是存储 数据元素 的 数据域,另一个是存储下一个结点地址的

数据结构 - 数组、矩阵、广义表存储

数组的定义 数组的定义 数组是下标index 和值value 组成的序对的集合. 在数组中,每个有定义的下标都与一个值对应,这个值称做数组元素. 每个序对形如: (index,value) 数组的顺序表示和实现 由于计算机的内存结构是一维的,因此用一维内存来表示多维数组,就必须按某种次序将数组元素排成一列序列,然后将这个线性序列存放在存储器中. 一般都是采用顺序存储的方法来表示数组 一维数组的顺序表示 设第一个数组元素a[0]的存储地址是loc(a[0]),若已知每个数组元素占k个存储单元,则下

数据结构——数组

说明:严蔚敏的<数据结构>(C语言版)学习笔记,记录一下,以备后面查看. ElemType *elem记录第一个元素的地址,也就是数组的首地址(基地址) int length 是实际数组中数据的长度 int listsize 是给数组分配的空间长度 #include <stdio.h> #include <malloc.h> #include <stdlib.h> #define LIST_INIT_SIZE 100 //线性表存储空间的初始分配量 #def

数据结构 数组,链表,栈,队列理解

数据结构 数据结构是指相互之间存在一种或多种特定关系的数据元素的集合.再简单描述一下:数据结构就是描述对象间逻辑关系的学科. 数据存储结构 常用的数据存储方式有两种:顺序存储,非顺序存储.顺序存储就是把数据存储在一块联系的存储介质(硬盘或内存等)中.反之则是非顺序存储. Java中的数组就是典型的顺序存储,链表就是非顺序存储.数组存储数据时会开辟出一块联系内存,按顺序存储.链表先不会开辟出一块内存来,而是只需要知道下一个节点存储的位置,就能把所以的数据连起来了.所以单向链表的最后一个节点是指向N

数据结构 数组笔记

/* 数组: 数组并不属于线性结构.数组是由类型相同的数据构成的有序集合 数组中的元素本身可以具有某种结构,而且元素的结构相同.数组 中的元素可以是一个单一的元素,也可以是一个线性表,因此数组 可以看做一般线性表的推广. 寻找数组中第k小的数 要查找第k小的数并不需要对整个数组进行排序,只需利用快速排序 的思想,每次将数据分成两堆,只要中间参量的的位置为k就不需要 再排序下去 */ /* 快速排序 快速排序是对冒泡排序的一种改进.基本思想是:通过一趟排序后将 需要排序的数据分割成独立的两部分,其