数据结构C语言版-稀疏矩阵的三元组顺序表存储表示和实现

数据结构C语言版-稀疏矩阵的三元组顺序表存储表示和实现
数据结构C语言版-稀疏矩阵的三元组顺序表存储表示和实现

typedef int ElemType;

// 稀疏矩阵的三元组顺序表存储表示

#define MAXSIZE 100 // 非零元个数的最大值

typedef struct

{

int i,j; // 行下标,列下标

ElemType e; // 非零元素值

}Triple;

typedef struct

{

Triple data[MAXSIZE+1]; // 非零元三元组表,data[0]未用

int mu,nu,tu; // 矩阵的行数、列数和非零元个数

}TSMatrix;

// 创建稀疏矩阵M

int CreateSMatrix(TSMatrix *M)

{

int i,m,n;

ElemType e;

int k;

printf("请输入矩阵的行数,列数,非零元素个数:(逗号)\n");

scanf("%d,%d,%d",&(*M).mu,&(*M).nu,&(*M).tu);

(*M).data[0].i=0; // 为以下比较顺序做准备

for(i = 1; i <= (*M).tu; i++)

{

do

{

printf("请按行序顺序输入第%d个非零元素所在的行(1~%d),"

"列(1~%d),元素值:(逗号)\n", i,(*M).mu,(*M).nu);

scanf("%d,%d,%d",&m,&n,&e);

k=0;

// 行或列超出范围

if(m < 1 || m > (*M).mu || n < 1 || n > (*M).nu)

k=1;

if(m < (*M).data[i-1].i || m == (*M).data[i-1].i

&& n <= (*M).data[i-1].j) // 行或列的顺序有错

k=1;

}while(k);

(*M).data[i].i = m; //行下标

(*M).data[i].j = n; //列下标

(*M).data[i].e = e; //该下标所对应的值

}

return 1;

}

// 销毁稀疏矩阵M,所有元素置空

void DestroySMatrix(TSMatrix *M)

{

(*M).mu=0;

(*M).nu=0;

(*M).tu=0;

}

// 输出稀疏矩阵M

void PrintSMatrix(TSMatrix M)

{

int i;

printf("\n%d行%d列%d个非零元素。\n",M.mu,M.nu,M.tu);

printf("%4s%4s%8s\n", "行", "列", "元素值");

for(i=1;i<=M.tu;i++)

printf("%4d%4d%8d\n",M.data[i].i,M.data[i].j,M.data[i].e); }

// 由稀疏矩阵M复制得到T

int CopySMatrix(TSMatrix M,TSMatrix *T)

{

(*T)=M;

return 1;

}

// AddSMatrix函数要用到

int comp(int c1,int c2)

{

int i;

if(c1

i=1;

else if(c1==c2)

i=0;

else

i=-1;

return i;

}

// 求稀疏矩阵的和Q=M+N

int AddSMatrix(TSMatrix M,TSMatrix N,TSMatrix *Q)

{

Triple *Mp,*Me,*Np,*Ne,*Qh,*Qe;

if(M.mu!=N.mu)

return 0;

if(M.nu!=N.nu)

return 0;

(*Q).mu=M.mu;

(*Q).nu=M.nu;

Mp=&M.data[1]; // Mp的初值指向矩阵M的非零元素首地址

Np=&N.data[1]; // Np的初值指向矩阵N的非零元素首地址

Me=&M.data[M.tu]; // Me指向矩阵M的非零元素尾地址

Ne=&N.data[N.tu]; // Ne指向矩阵N的非零元素尾地址

Qh=Qe=(*Q).data; // Qh、Qe的初值指向矩阵Q的非零元素首地址的前一地址while(Mp <= Me && Np <= Ne)

{

Qe++;

switch(comp(Mp->i,Np->i))

{

case 1:

*Qe=*Mp;

Mp++;

break;

case 0:

// M、N矩阵当前非零元素的行相等,继续比较列

switch(comp(Mp->j,Np->j))

{

case 1:

*Qe=*Mp;

Mp++;

break;

case 0:

*Qe=*Mp;

Qe->e+=Np->e;

if(!Qe->e) // 元素值为0,不存入压缩矩阵

Qe--;

Mp++;

Np++;

break;

case -1:

*Qe=*Np;

Np++;

}

break;

case -1:

*Qe=*Np;

Np++;

}

}

if(Mp>Me) // 矩阵M的元素全部处理完毕

while(Np<=Ne)

{

Qe++;

*Qe=*Np;

Np++;

}

if(Np>Ne) // 矩阵N的元素全部处理完毕

while(Mp<=Me)

{

Qe++;

*Qe=*Mp;

Mp++;

}

(*Q).tu=Qe-Qh; // 矩阵Q的非零元素个数

return 1;

}

// 求稀疏矩阵的差Q=M-N

int SubtSMatrix(TSMatrix M,TSMatrix N,TSMatrix *Q)

{

int i;

for(i=1;i<=N.tu;i++)

N.data[i].e*=-1;

AddSMatrix(M,N,Q);

return 1;

}

// 求稀疏矩阵的乘积Q=M*N

int MultSMatrix(TSMatrix M,TSMatrix N,TSMatrix *Q)

{

int i,j,h=M.mu,l=N.nu,Qn=0;

// h,l分别为矩阵Q的行、列值,Qn为矩阵Q的非零元素个数,初值为0 ElemType *Qe;

if(M.nu!=N.mu)

return 0;

(*Q).mu=M.mu;

(*Q).nu=N.nu;

Qe=(ElemType *)malloc(h*l*sizeof(ElemType)); // Qe为矩阵Q的临时数组// 矩阵Q的第i行j列的元素值存于*(Qe+(i-1)*l+j-1)中,初值为0

for(i=0;i

*(Qe+i)=0; // 赋初值0

for(i=1;i<=M.tu;i++) // 矩阵元素相乘,结果累加到Qe

for(j=1;j<=N.tu;j++)

if(M.data[i].j==N.data[j].i)

*(Qe+(M.data[i].i-1)*l+N.data[j].j-1) +=

M.data[i].e * N.data[j].e;

for(i=1;i<=M.mu;i++)

for(j=1;j<=N.nu;j++)

if(*(Qe+(i-1)*l+j-1)!=0)

{

Qn++;

(*Q).data[Qn].e=*(Qe+(i-1)*l+j-1);

(*Q).data[Qn].i=i;

(*Q).data[Qn].j=j;

}

free(Qe);

(*Q).tu=Qn;

return 1;

}

// 算法5.1 P99

// 求稀疏矩阵M的转置矩阵T。

int TransposeSMatrix(TSMatrix M,TSMatrix *T)

{

int p,q,col;

(*T).mu=M.nu;

(*T).nu=M.mu;

(*T).tu=M.tu;

if((*T).tu)

{

q=1;

for(col=1;col<=M.nu;++col) //先将列转换成行

for(p=1;p<=M.tu;++p) //再将行转换成列

if(M.data[p].j==col)

{

(*T).data[q].i=M.data[p].j;

(*T).data[q].j=M.data[p].i;

(*T).data[q].e=M.data[p].e;

++q;

}

}

return 1;

}

// 算法5.2 P100

// 快速求稀疏矩阵M的转置矩阵T。

int FastTransposeSMatrix(TSMatrix M,TSMatrix *T)

{

int p,q,t,col,*num,*cpot;

num=(int *)malloc((M.nu+1)*sizeof(int)); // 生成数组([0]不用)cpot=(int *)malloc((M.nu+1)*sizeof(int)); // 生成数组([0]不用)(*T).mu=M.nu;

(*T).nu=M.mu;

(*T).tu=M.tu;

if((*T).tu)

{

for(col=1;col<=M.nu;++col)

num[col]=0; // 设初值

for(t=1;t<=M.tu;++t) // 求M中每一列含非零元素个数

++num[M.data[t].j];

cpot[1]=1;

// 求第col列中第一个非零元在(*T).data中的序号

for(col=2;col<=M.nu;++col)

cpot[col]=cpot[col-1]+num[col-1];

for(p=1;p<=M.tu;++p)

{

col=M.data[p].j;

q=cpot[col];

(*T).data[q].i=M.data[p].j;

(*T).data[q].j=M.data[p].i;

(*T).data[q].e=M.data[p].e;

++cpot[col];

}

}

free(num);

free(cpot);

return 1;

}

int main()

{

TSMatrix A,B,C;

printf("创建矩阵A: ");

CreateSMatrix(&A);

PrintSMatrix(A);

printf("由矩阵A复制矩阵B: ");

CopySMatrix(A,&B);

PrintSMatrix(B);

DestroySMatrix(&B);

printf("销毁矩阵B后:\n");

PrintSMatrix(B);

printf("重创矩阵B:(注意与矩阵A的行、列数相同,这样方便后面的测试"

"行、列分别为%d,%d)\n", A.mu, A.nu);

CreateSMatrix(&B);

PrintSMatrix(B);

printf("矩阵C1(A+B): ");

AddSMatrix(A,B,&C);

PrintSMatrix(C);

DestroySMatrix(&C);

printf("矩阵C2(A-B): ");

SubtSMatrix(A,B,&C);

PrintSMatrix(C);

DestroySMatrix(&C);

printf("矩阵C3(A的转置): ");

TransposeSMatrix(A,&C);

PrintSMatrix(C);

DestroySMatrix(&A);

DestroySMatrix(&B);

DestroySMatrix(&C);

printf("创建矩阵A2: ");

CreateSMatrix(&A);

PrintSMatrix(A);

printf("创建矩阵B3:(行数应与矩阵A2的列数相同=%d)\n",A.nu); CreateSMatrix(&B);

PrintSMatrix(B);

printf("矩阵C5(A*B): ");

MultSMatrix(A,B,&C);

PrintSMatrix(C);

DestroySMatrix(&A);

DestroySMatrix(&B);

DestroySMatrix(&C);

printf("创建矩阵A: ");

CreateSMatrix(&A);

PrintSMatrix(A);

FastTransposeSMatrix(A,&B);

printf("矩阵B(A的快速转置): ");

PrintSMatrix(B);

DestroySMatrix(&A);

DestroySMatrix(&B);

system("pause");

return 0;

}

/*

输出效果:

创建矩阵A: 请输入矩阵的行数,列数,非零元素个数:(逗号)

3,3,3

请按行序顺序输入第1个非零元素所在的行(1~3),列(1~3),元素值:(逗号) 1,1,1

请按行序顺序输入第2个非零元素所在的行(1~3),列(1~3),元素值:(逗号) 1,3,2

请按行序顺序输入第3个非零元素所在的行(1~3),列(1~3),元素值:(逗号) 3,3,3

3行3列3个非零元素。

行列元素值

1 1 1

1 3 2

3 3 3

由矩阵A复制矩阵B:

3行3列3个非零元素。

行列元素值

1 1 1

1 3 2

3 3 3

销毁矩阵B后:

0行0列0个非零元素。

行列元素值

重创矩阵B:(注意与矩阵A的行、列数相同,这样方便后面的测试行、列分别为3,3) 请输入矩阵的行数,列数,非零元素个数:(逗号)

3,3,3

请按行序顺序输入第1个非零元素所在的行(1~3),列(1~3),元素值:(逗号)

1,2,1

请按行序顺序输入第2个非零元素所在的行(1~3),列(1~3),元素值:(逗号)

2,1,2

请按行序顺序输入第3个非零元素所在的行(1~3),列(1~3),元素值:(逗号)

3,1,3

3行3列3个非零元素。

行列元素值

1 2 1

2 1 2

3 1 3

矩阵C1(A+B):

3行3列6个非零元素。

行列元素值

1 1 1

1 2 1

1 3 2

2 1 2

3 1 3

3 3 3

矩阵C2(A-B):

3行3列6个非零元素。

行列元素值

1 1 1

1 2 -1

1 3 2

2 1 -2

3 1 -3

3 3 3

矩阵C3(A的转置):

3行3列3个非零元素。

行列元素值

1 1 1

3 1 2

3 3 3

创建矩阵A2: 请输入矩阵的行数,列数,非零元素个数:(逗号)

3,3,3

请按行序顺序输入第1个非零元素所在的行(1~3),列(1~3),元素值:(逗号) 1,1,1

请按行序顺序输入第2个非零元素所在的行(1~3),列(1~3),元素值:(逗号) 1,3,2

请按行序顺序输入第3个非零元素所在的行(1~3),列(1~3),元素值:(逗号) 3,3,3

3行3列3个非零元素。

行列元素值

1 1 1

1 3 2

3 3 3

创建矩阵B3:(行数应与矩阵A2的列数相同=3)

请输入矩阵的行数,列数,非零元素个数:(逗号)

3,3,2

请按行序顺序输入第1个非零元素所在的行(1~3),列(1~3),元素值:(逗号) 1,3,1

请按行序顺序输入第2个非零元素所在的行(1~3),列(1~3),元素值:(逗号) 2,2,2

3行3列2个非零元素。

行列元素值

1 3 1

2 2 2

矩阵C5(A*B):

3行3列1个非零元素。

行列元素值

1 3 1

创建矩阵A: 请输入矩阵的行数,列数,非零元素个数:(逗号)

3,3,2

请按行序顺序输入第1个非零元素所在的行(1~3),列(1~3),元素值:(逗号) 1,2,2

请按行序顺序输入第2个非零元素所在的行(1~3),列(1~3),元素值:(逗号) 3,1,2

3行3列2个非零元素。

行列元素值

1 2 2

3 1 2

矩阵B(A的快速转置):

3行3列2个非零元素。

行列元素值

1 3 2

2 1 2

请按任意键继续. . . */

数据结构试题集(包含答案 完整版)

第一章概论 一、选择题 1、研究数据结构就是研究(D )。 A. 数据的逻辑结构 B. 数据的存储结构 C. 数据的逻辑结构和存储结构 D. 数据的逻辑结构、存储结构及其基本操作 2、算法分析的两个主要方面是( A )。 A. 空间复杂度和时间复杂度 B. 正确性和简单性 C. 可读性和文档性 D. 数据复杂性和程序复杂性 3、具有线性结构的数据结构是( D )。 A. 图 B. 树 C. 广义表 D. 栈 4、计算机中的算法指的是解决某一个问题的有限运算序列,它必须具备输入、输出、(B )等5个特性。 A. 可执行性、可移植性和可扩充性 B. 可执行性、有穷性和确定性 C. 确定性、有穷性和稳定性 D. 易读性、稳定性和确定性 5、下面程序段的时间复杂度是( C )。 for(i=0;i

O(m+n) 6、算法是(D )。 A. 计算机程序 B. 解决问题的计算方法 C. 排序算法 D. 解决问题的有限运算序列 7、某算法的语句执行频度为(3n+nlog2n+n2+8),其时间复杂度表示(C )。 A. O(n) B. O(nlog2n) C. O(n2) D. O(log2n) 8、下面程序段的时间复杂度为( C )。 i=1; while(i<=n) i=i*3; A. O(n) B. O(3n) C. O(log3n) D. O(n3) 9、数据结构是一门研究非数值计算的程序设计问题中计算机的数据元素以及它们之间的()和运算等的学科。 A. 结构 B. 关系 C. 运算 D. 算法 10、下面程序段的时间复杂度是(A )。 i=s=0; while(s

数据结构顺序表真题

第二章复习题 本章重点掌握:线性结构特点,顺序存储结构和链式存储结构特点。 1.在顺序表中插入或删除一个元素,需要平均移动( 一半 )元素,具体移动的元素个数与( 插入或删除的位置 )有关。插入时平均 次数(n/2 ),删除时平均次数((n-1)/2 )。 2.有一个含头结点的循环链表,头指针为 head, 则其为空的条件是:( C ) A)head==NULL B)head->next==NULL C)head->next==head 3.在长度为 n 的顺序表的第 i 个位置上插入一个元素(1≤i≤n+1),元素的移动次数为:( A ) A) n – i + 1 B) n – i C) i D) i – 1 4.对于只在表的首、尾两端进行插入操作的线性表,宜采用的存储结构为( C ) A)顺序表B) 用头指针表示的循环单链表 C) 用尾指针表示的循环单链表D) 单链表 5.设单链表中结点的结构为(data, link)。已知指针 q 所指结点是指针 p 所指结点的直接前驱,若在*q 与*p 之间插入结点*s,则应执行下列哪一个操作?( B ) A)s->link = p->link;p->link = s;(B) q->link = s;s->link = p; (C) p->link = s->link;s->link = p;(D) p->link = s;s->link = q; 6.设单链表中结点的结构为(data, link)。已知指针 p 所指结点不是尾结点,若在*p 之后插入结点*s,则应执行下列哪一个操作?(B)

A)s->link = p;p->link = s;(B) s->link = p->link;p->link = s; (C) s->link = p->link;p = s;(D) p->link = s;s->link = p; 7.设单链表中结点的结构为(data, link)。若想摘除结点*p 的直接后继,则应执行下列哪一个操作?(A) (A) p->link = p->link->link; (B) p = p->link;p->link = p->link->link; (C) p->link = p->link;(D) p = p->link->link; 8.设单循环链表中结点的结构为(data, link),且 rear 是指向非空的 带表头结点的单循环链表的尾结点的指针。若想删除链表第一个结点,则应执行下列哪一个操作?(D) (A)s = rear;rear = rear->link;delete s; (B)rear = rear->link;delete rear; (C)rear = rear->link->link;delete rear; (D)s = rear->link->link;rear->link->link = s->link; delete s; (rear 指向尾结点,rear->link->link 指向第一个结点,第一个结点变为原来的第二个结点) 9.设双向循环链表中结点的结构为(data, lLink, rLink),且不带表头 结点。若想在指针 p 所指结点之后插入指针 s 所指结点,则应执 行下列哪一个操作?( D )

试举一个数据结构的例子、叙述其逻辑结构、存储结构、运算三个方面的内容。

数据结构复习笔记 作者: 网络转载发布日期: 无 数据就是指能够被计算机识别、存储和加工处理的信息的载体。 数据元素是数据的基本单位,有时一个数据元素可以由若干个数据项组成。数据项是具有独立含义的最小标识单位。如整数这个集合中,10这个数就可称是一个数据元素.又比如在一个数据库(关系式数据库)中,一个记录可称为一个数据元素,而这个元素中的某一字段就是一个数据项。 数据结构的定义虽然没有标准,但是它包括以下三方面内容:逻辑结构、存储结构、和对数据的操作。这一段比较重要,我用自己的语言来说明一下,大家看看是不是这样。 比如一个表(数据库),我们就称它为一个数据结构,它由很多记录(数据元素)组成,每个元素又包括很多字段(数据项)组成。那么这张表的逻辑结构是怎么样的呢? 我们分析数据结构都是从结点(其实也就是元素、记录、顶点,虽然在各种情况下所用名字不同,但说的是同一个东东)之间的关系来分析的,对于这个表中的任一个记录(结点),它只有一个直接前趋,只有一个直接后继(前趋后继就是前相邻后相邻的意思),整个表只有一个开始结点和一个终端结点,那我们知道了这些关系就能明白这个表的逻辑结构了。 而存储结构则是指用计算机语言如何表示结点之间的这种关系。如上面的表,在计算机语言中描述为连续存放在一片内存单元中,还是随机的存放在内存中再用指针把它们链接在一起,这两种表示法就成为两种不同的存储结构。(注意,在本课程里,我们只在高级语言的层次上讨论存储结构。) 第三个概念就是对数据的运算,比如一张表格,我们需要进行查找,增加,修改,删除记录等工作,而怎么样才能进行这样的操作呢? 这也就是数据的运算,它不仅仅是加减乘除这些算术运算了,在数据结构中,这些运算常常涉及算法问题。 弄清了以上三个问题,就可以弄清数据结构这个概念。 -------------------------------------------------------------------------------- 通常我们就将数据的逻辑结构简称为数据结构,数据的逻辑结构分两大类:线性结构和非线性结构(这两个很容易理解) 数据的存储方法有四种:顺序存储方法、链接存储方法、索引存储方法和散列存储方法。-------------------------------------------------------------------------------- 下一个是难点问题,就是算法的描述和分析,主要是算法复杂度的分析方法及其运用。首先了解一下几个概念。一个是时间复杂度,一个是渐近时间复杂度。前者是某个算法的时间耗费,它是该算法所求解问题规模n的函数,而后者是指当问题规模趋向无穷大时,该算法时间复杂度的数量级。 当我们评价一个算法的时间性能时,主要标准就是算法的渐近时间复杂度,因此,在算法分析时,往往对两者不予区分,经常是将渐近时间复杂度T(n)=O(f(n)简称为时间复杂度,其中的f(n)一般是算法中频度最大的语句频度。 此外,算法中语句的频度不仅与问题规模有关,还与输入实例中各元素的取值相关。但是我们总是考虑在最坏的情况下的时间复杂度。以保证算法的运行时间不会比它更长。 常见的时间复杂度,按数量级递增排列依次为:常数阶O(1)、对数阶O(log2n)、线性阶O(n)、线性对数阶O(nlog2n)、平方阶O(n^2)、立方阶O(n^3)、k次方阶O(n^k)、指数阶O(2^n)。 时间复杂度的分析计算请看书本上的例子,然后我们通过做练习加以领会和巩固。 数据结构习题一 --------------------------------------------------------------------------------

四种基本的存储结构

四种基本的存储结构 Prepared on 22 November 2020

数据的四种基本存储方法 数据的存储结构可用以下四种基本存储方法得到: (1)顺序存储方法 该方法把逻辑上相邻的结点存储在物理位置上相邻的存储单元里,结点间的逻辑关系由存储单元的邻接关系来体现。 由此得到的存储表示称为顺序存储结构(Sequential Storage Structure),通常借助程序语言的数组描述。 该方法主要应用于线性的数据结构。非线性的数据结构也可通过某种线性化的方法实现顺序存储。 (2)链接存储方法 该方法不要求逻辑上相邻的结点在物理位置上亦相邻,结点间的逻辑关系由附加的指针字段表示。由此得到的存储表示称为链式存储结构(Linked Storage Structure),通常借助于程序语言的指针类型描述。 (3)索引存储方法 该方法通常在储存结点信息的同时,还建立附加的索引表。

索引表由若干索引项组成。若每个结点在索引表中都有一个索引项,则该索引表称之为稠密索引(Dense Index)。若一组结点在索引表中只对应一个索引项,则该索引表称为稀疏索引(Spare Index)。索引项的一般形式是: (关键字、地址) 关键字是能唯一标识一个结点的那些数据项。稠密索引中索引项的地址指示结点所在的存储位置;稀疏索引中索引项的地址指示一组结点的起始存储位置。 (4)散列存储方法 该方法的基本思想是:根据结点的关键字直接计算出该结点的存储地址。 四种基本存储方法,既可单独使用,也可组合起来对数据结构进行存储映像。 同一逻辑结构采用不同的存储方法,可以得到不同的存储结构。选择何种存储结构来表示相应的逻辑结构,视具体要求而定,主要考虑运算方便及算法的时空要求。 数据结构三方面的关系

数据结构顺序表的查找插入与删除

一、上机实验的问题和要求: 顺序表的查找、插入与删除。设计算法,实现线性结构上的顺序表的产生以及元素的查找、插入与删除。具体实现要求: 1.从键盘输入10个整数,产生顺序表,并输入结点值。 2.从键盘输入1个整数,在顺序表中查找该结点的位置。若找到,输出结点的位置;若找 不到,则显示“找不到”。 3.从键盘输入2个整数,一个表示欲插入的位置i,另一个表示欲插入的数值x,将x插 入在对应位置上,输出顺序表所有结点值,观察输出结果。 4.从键盘输入1个整数,表示欲删除结点的位置,输出顺序表所有结点值,观察输出结果。 二、源程序及注释: #include #include /*顺序表的定义:*/ #include #define ListSize 100 /*表空间大小可根据实际需要而定,这里假设为100*/ typedef int DataType; /*DataType可以是任何相应的数据类型如int, float或char*/ typedef struct { DataType data[ListSize]; /*向量data用于存放表结点*/ int length; /*当前的表长度*/ }SeqList; void main() { SeqList L; int i,x; int n=10; /*欲建立的顺序表长度*/ L.length=0; void CreateList(SeqList *L,int n); void PrintList(SeqList L,int n); int LocateList(SeqList L,DataType x); void InsertList(SeqList *L,DataType x,int i); void DeleteList(SeqList *L,int i); CreateList(&L,n); /*建立顺序表*/ PrintList(L,n); /*打印顺序表*/ printf("输入要查找的值:"); scanf("%d",&x); i=LocateList(L,x); /*顺序表查找*/ printf("输入要插入的位置:"); scanf("%d",&i); printf("输入要插入的元素:"); scanf("%d",&x); InsertList(&L,x,i); /*顺序表插入*/

《数据结构》填空作业题(答案)

《数据结构》填空作业题答案 第1章绪论(已校对无误) 1.数据结构包括数据的逻辑结构、数据的存储结构和数据的运算三方面的内容。 2.程序包括两个内容:数据结构和算法。 3. 数据结构的形式定义为:数据结构是一个二元组:Data Structure =(D,S)。 4. 数据的逻辑结构在计算机存储器内的表示,称为数据的存储结构。 5. 数据的逻辑结构可以分类为线性结构和非线性结构两大类。 6. 在图状结构中,每个结点的前驱结点数和后继结点数可以有多个。 7. 在树形结构中,数据元素之间存在一对多的关系。 8. 数据的物理结构,指数据元素在计算机中的标识(映象),也即存储结构。 9. 数据的逻辑结构包括线性结构、树形结构和图形结构3种类型,树型结构和有向图结构合称为非线性结构。 10. 顺序存储结构是把逻辑上相邻的结点存储在物理上连续的存储单元里,结点之间的逻辑关系由存储单元位置的邻接关系来体现。 11. 链式存储结构是把逻辑上相邻的结点存储在物理上任意的存储单元里,节点之间的逻辑关系由附加的指针域来体现。 12. 数据的存储结构可用4种基本的存储方法表示,它们分别是顺序存储、链式存储、索引存储和散列存储。 13. 线性结构反映结点间的逻辑关系是一对一的,非线性结构反映结点间的逻辑关系是一对多或多对多。 14. 数据结构在物理上可分为顺序存储结构和链式存储结构。 15. 我们把每种数据结构均视为抽象类型,它不但定义了数据的表示方式,还给出了处理数据的实现方法。 16. 数据元素可由若干个数据项组成。 17. 算法分析的两个主要方面是时间复杂度和空间复杂度。 18. 一个算法的时间复杂度是用该算法所消耗的时间的多少来度量的,一个算法的空间复杂度是用该算法在运行过程中所占用的存储空间的大小来度量的。 19. 算法具有如下特点:有穷性、确定性、可行性、输入、输出。 20. 对于某一类特定的问题,算法给出了解决问题的一系列操作,每一操作都有它的确切 的定义,并在有穷时间内计算出结果。 21. 下面程序段的时间复杂度为㏒3n 。

数据结构实现顺序表的各种基本运算(20210215233821)

实现顺序表的各种基本运算 一、实验目的 了解顺序表的结构特点及有关概念,掌握顺序表的各种基本操作算法思想及其实现。 二、实验内容 编写一个程序,实现顺序表的各种基本运算: 1、初始化顺序表; 2 、顺序表的插入; 3、顺序表的输出; 4 、求顺序表的长度 5 、判断顺序表是否为空; 6 、输出顺序表的第i位置的个元素; 7 、在顺序表中查找一个给定元素在表中的位置; 8、顺序表的删除; 9 、释放顺序表 三、算法思想与算法描述简图

主函数main

四、实验步骤与算法实现 #in clude #in clude #defi ne MaxSize 50 typedef char ElemType; typedef struct {ElemType data[MaxSize]; in t le ngth; void In itList(SqList*&L)〃 初始化顺序表 L {L=(SqList*)malloc(sizeof(SqList)); L->le ngth=0; for(i=0;ile ngth;i++) prin tf("%c ",L->data[i]); } void DestroyList(SqList*&L)〃 {free(L); } int ListEmpty(SqList*L)〃 {retur n( L->le ngth==O); } int Listle ngth(SqList*L)〃 {return(L->le ngth); } void DispList(SqList*L)〃 {int i; 释放顺序表 L

数据结构复习要点(整理版).docx

第一章数据结构概述 基本概念与术语 1.数据:数据是对客观事物的符号表示,在计算机科学中是指所有能输入到计算机中并被计算机程序所处理的符号的总称。 2. 数据元素:数据元素是数据的基本单位,是数据这个集合中的个体,也称之为元素,结点,顶点记录。 (补充:一个数据元素可由若干个数据项组成。数据项是数据的不可分割的最小单位。 ) 3.数据对象:数据对象是具有相同性质的数据元素的集合,是数据的一个子集。(有时候也 叫做属性。) 4.数据结构:数据结构是相互之间存在一种或多种特定关系的数据元素的集合。 (1)数据的逻辑结构:数据的逻辑结构是指数据元素之间存在的固有逻辑关系,常称为数据结构。 数据的逻辑结构是从数据元素之间存在的逻辑关系上描述数据与数据的存储无关,是独立于计算机的。 依据数据元素之间的关系,可以把数据的逻辑结构分成以下几种: 1. 集合:数据中的数据元素之间除了“同属于一个集合“的关系以外,没有其他关系。 2. 线性结构:结构中的数据元素之间存在“一对一“的关系。若结构为非空集合,则除了第一个元素之外,和最后一个元素之外,其他每个元素都只有一个直接前驱和一个直接后继。 3. 树形结构:结构中的数据元素之间存在“一对多“的关系。若数据为非空集,则除了第一个元素 (根)之外,其它每个数据元素都只有一个直接前驱,以及多个或零个直接后继。 4. 图状结构:结构中的数据元素存在“多对多”的关系。若结构为非空集,折每个数据可有多个(或零个)直接后继。 (2)数据的存储结构:数据元素及其关系在计算机内的表示称为数据的存储结构。想要计算机处理数据,就必须把数据的逻辑结构映射为数据的存储结构。逻辑结构可以映射为以下两种存储结构: 1. 顺序存储结构:把逻辑上相邻的数据元素存储在物理位置也相邻的存储单元中,借助元素在存储器中的相对位置来表示数据之间的逻辑关系。 2. 链式存储结构:借助指针表达数据元素之间的逻辑关系。不要求逻辑上相邻的数据元素物理位置上也相邻。 5. 时间复杂度分析:1.常量阶:算法的时间复杂度与问题规模n 无关系T(n)=O(1) 2. 线性阶:算法的时间复杂度与问题规模 n 成线性关系T(n)=O(n) 3. 平方阶和立方阶:一般为循环的嵌套,循环体最后条件为i++ 时间复杂度的大小比较: O(1)< O(log 2 n)< O(n )< O(n log 2 n)< O(n2)< O(n3)< O(2 n )

数据结构课后标准答案

第1章绪论 1.简述下列概念:数据、数据元素、数据项、数据对象、数据结构、逻辑结构、存储结构、抽象数据类型。 答案: 数据:是客观事物的符号表示,指所有能输入到计算机中并被计算机程序处理的符号的总称。如数学计算中用到的整数和实数,文本编辑所用到的字符串,多媒体程序处理的图形、图像、声音、动画等通过特殊编码定义后的数据。 数据元素:是数据的基本单位,在计算机中通常作为一个整体进行考虑和处理。在有些情况下,数据元素也称为元素、结点、记录等。数据元素用于完整地描述一个对象,如一个学生记录,树中棋盘的一个格局(状态)、图中的一个顶点等。 数据项:是组成数据元素的、有独立含义的、不可分割的最小单位。例如,学生基本信息表中的学号、姓名、性别等都是数据项。 数据对象:是性质相同的数据元素的集合,是数据的一个子集。例如:整数数据对象是集合N={0,±1,±2,…},字母字符数据对象是集合C={‘A’,‘B’,…,‘Z’,‘a’,‘b’,…,‘z’},学生基本信息表也可是一个数据对象。 数据结构:是相互之间存在一种或多种特定关系的数据元素的集合。换句话说,数据结构是带“结构”的数据元素的集合,“结构”就是指数据元素之间存在的关系。 逻辑结构:从逻辑关系上描述数据,它与数据的存储无关,是独立于计算机的。因此,数据的逻辑结构可以看作是从具体问题抽象出来的数学模型。 存储结构:数据对象在计算机中的存储表示,也称为物理结构。 抽象数据类型:由用户定义的,表示应用问题的数学模型,以及定义在这个模型上的一组操作的总称。具体包括三部分:数据对象、数据对象上关系的集合和对数据对象的基本操作的集合。 2.试举一个数据结构的例子,叙述其逻辑结构和存储结构两方面的含义和相互关系。 答案: 例如有一张学生基本信息表,包括学生的学号、姓名、性别、籍贯、专业等。每个学生基本信息记录对应一个数据元素,学生记录按顺序号排列,形成了学生基本信息记录的线性序列。对于整个表来说,只有一个开始结点(它的前面无记录)和一个终端结点(它的后面无记录),其他的结点则各有一个也只有一个直接前趋和直接后继。学生记录之间的这种关系就确定了学生表的逻辑结构,即线性结构。 这些学生记录在计算机中的存储表示就是存储结构。如果用连续的存储单元(如用数组表示)来存放这些记录,则称为顺序存储结构;如果存储单元不连续,而是随机存放各个记录,然后用指针进行链接,则称为链式存储结构。 即相同的逻辑结构,可以对应不同的存储结构。 3.简述逻辑结构的四种基本关系并画出它们的关系图。 答案: (1)集合结构 数据元素之间除了“属于同一集合”的关系外,别无其他关系。例如,确定一名学生是否为班级成员,只需将班级看做一个集合结构。 (2)线性结构 数据元素之间存在一对一的关系。例如,将学生信息数据按照其入学报到的时间先后顺序进行排列,将组成一个线性结构。 (3)树结构

数据结构C语言版 串的定长顺序存储表示和实现

#include #include #include #define OK 1 #define ERROR 0 #define TRUE 1 #define FALSE 0 #define OVERFLOW -2 #define MAXSTRLEN 255 typedef int ElemType; typedef int Status; typedef unsigned char SString[MAXSTRLEN+1]; //串赋值操作 Status StrAssign(SString T,char chars[]){ // 生成一个其值等于chars的串T int i; if(strlen(chars)>MAXSTRLEN) return ERROR; T[0]=strlen(chars); for(i=0;i<=T[0];i++){ T[i+1]=chars[i];} return OK; }//StrAssign //输出串 void StrPrint(SString S){ int i; for(i=1;i<=S[0];i++){ printf("%c",S[i]); } printf("\n"); }//PrnStr //串复制操作 Status StrCopy(SString T,SString S){ // 由串S复制得串T int i; for(i=1;i<=S[0];i++) T[i]=S[i]; T[0]=S[0]; return OK; }//StrCopy //判空操作 Status StrEmpty(SString S){ if(S[0]==0) return OK;

数据结构习题(包含全部答案解析)

数据结构习题集(自编) 第一章绪论 一、选择题 1.数据结构是一门研究非数值计算的程序设计问题中的操作对象以及它们之间的()和运算的学科。 A.结构B.关系 C.运算 D.算法 2.在数据结构中,从逻辑上可以把数据结构分成()。 A.动态结构和静态结构 B.紧凑结构和非紧凑结构 C.线性结构和非线性结构 D.逻辑结构和存储结构 3.线性表的逻辑顺序和存储顺序总是一致的,这种说法()。 A.正确B.不正确 C.无法确定 D.以上答案都不对4.算法分析的目的是()。 A.找出算法的合理性 B.研究算法的输人与输出关系 C.分析算法的有效性以求改进 D.分析算法的易懂性 5. 算法的时间复杂度取决于() A.问题的规模B待处理数据的初态 C. A和B 6.一个算法应该是()。 A.程序B.问题求解步骤的描述 C.要满足五个基本特性 D.A和C. 7. 下面关于算法说法错误的是() A.算法最终必须由计算机程序实现 B.为解决某问题的算法与为该问题编写的程序含义是相同的 C. 算法的可行性是指指令不能有二义性 D. 以上几个都是错误的 8.以下与数据的存储结构无关的术语是()。 A.循环队列 B. 链表 C. 哈希表 D. 栈 9.在下面的程序段中,对x的赋值语句的频度为() for(i=0;i

实验一数据结构顺序表的插入和删除

实验一顺序表的操作 1. 实验题目:顺序表的操作 2.实验目的和要求: 1)了解顺 序表的基本概念、顺序表结构的定义及在顺序表上的基本操作(插入、 删除、查找以及线性表合并 )。 2)通过在 Turbo C ( WinTc ,或 visual stdio6 )实现以上操作的 C 语言 代码。 3)提前了解实验相关的知识(尤其是 C 语 言)。 3.实验内容:(二选一) 1) 顺序表的插入算法, 删除算法, 顺序表的合并算法 2) 与线性表应用相关的实例( 自己选择具体实例) 4.部分参考实验代码: ⑴ 顺序表结构的定义: #include #define MAXLEN 255 typedef int ElemType; typedef struct { ElemType elem[MAXLEN]; int length; }sqList; ⑵ 顺序表前插(在第i 号元素前插入一个新的元素) int ListInsert(sqList *la,int i,int x) { int j; if(i<0||i>la-> length +1) { printf( “ n the value of i is wrong! ” ); return 0; } if(la-> length +1>=MAXLEN) { printf( “ n overflow! ” ); return 0; }

. for(j=la-> length;j>=i;j--) la->list[j+1]=la->list[j]; la->list[i]=x; la-> length ++; return 1; } ⑶ 顺序表删除 int ListDelete(sqList *la,int i) { if(i<0||i>la-> length ) { printf( “ return 0; n”); } for(i;i length;i++) la->list[i-1]=la->list[i]; la-> length --; return 1; } 5.附录:实验预备知识: ⑴ 复习 C 语言中数组的用法。 ⑵ 了解线性表和顺序表的概念,顺序表的定义方法; 线性表是n 个数据元素的有限序列,至于每个数据元素的具体含义,在不同的情况下各不相同。 顺序表是线性表的顺序存储表示,是用一组地址连续的存储单元依次存储线性表的数据元素。 在 C 语言中,顺序表是用数组来实现的。 ⑶ 掌握线性表在顺序存储结构上实现基本操作:查找、插入、删除和 合并的算法。 在实现这些算法的时候,要注意判断输入数据的合法性,除此之外还要要注意以下内容: 在实现查找的时候,首先要判断该顺序表是否为空,其次要判断查找后的结果(查到时输出查到的数据,未查到时给出未查到提 示)。 在实现插入的时候,首先要判断该顺序表是否为满,如为满则报错 (此时要注意:顺序表是用数组来实现的,它不能随机分配空 间);如不为满,则需判断要插入的位置是否合法(例如:如果 一个线性表的元素只有10 个,而要在第0 个元素前插入或在第 11 个元素后插入就为不合法)。其次要注意是前插还是后插,两

数据结构顺序存储结构

数据结构顺序表 第一种方法: #include #define MAX_SIZE 50 typedefintElemType; //自定义类型 typedefstruct { //结构体 ElemTypedata[MAX_SIZE]; intlen; }SqList; /*参数一:顺序表参数二:一个数组参数三:顺序表长度*/ voidcreateSqList(SqList&L,int a[], int n){ for(int i = 0; i < n; i++){ L.data[i]=a[i]; } L.len = n; } //打印输出顺序表 voidprintSqList(SqList L){ printf("打印顺序表:"); for(int i = 0; i

第二种方法: #include #include #define MAX_SIZE 50 typedefintElemType; //自定义类型 typedefstruct { //结构体 ElemTypedata[MAX_SIZE]; intlen; }SqList; /*参数一:顺序表参数二:一个数组参数三:顺序表长度*/ voidcreateSqList(SqList *L,int a[], int n){ for(int i = 0; i < n; i++){ L->data[i]=a[i]; } L->len = n; } //打印输出顺序表 voidprintSqList(SqList *L){ printf("打印表:"); for(int i = 0; i < L->len; i++){ printf("%d ",L->data[i]); } printf("\n"); } int main(){ //初始化一个空表 SqList *L; L=(SqList *)malloc(sizeof(SqList)); L->len=0; int i; //初始化数组 int array[5]; for(i=0;i<5;i++){ array[i]=i; } createSqList(L,array, 5); printSqList(L); }

数据结构顺序表(电话通讯录)

数据结构用顺序表实现的电话通讯录(C语言) #include #include #include #include #define FALSE 0 #define ERROR 0 #define OK 1 #define INFEASIBLE -1 #define LIST_INIT_SIZE 10 #define LIST_INCREMENT 5 #define N 5 typedefint Status; typedefstruct { char name[10]; //姓名 char num[15]; //号码 }student; typedefstruct { student *elem; //存储空间基址 int length; //当前长度 intlistsize; //当前分配的存储空间(以sizeof(student)为单位) }Sqlist; Sqlist L; //定义全局变量L 为Sqllist类型 Status ListInsert(Sqlist&L,inti,student e) { //插入学生信息到顺序表L中 int j; student *newbase; if(i<1||i>L.length+1) return ERROR; //i值不合法 if(L.length>=L.listsize) //当前存储空间已满,增加分配 { newbase=(student *)realloc(L.elem,(LIST_INIT_SIZE+LIST_INCREMENT)*(sizeof(student))); if(!newbase) //存储分配失败 exit(OVERFLOW); L.elem=newbase; //新基址 L.listsize+=LIST_INCREMENT; //增加存储容量 } for(j=L.length;j>=i;j--) L.elem[j]=L.elem[j-1]; //插入位置及之后元素的右移 L.elem[i-1]=e; L.length++; return OK;

数据结构练习题--2011级--参考答案

选择题: 1.1数据结构在计算机内存中的表示是指: A.数据的存储结构 B.数据结构 C.数据的逻辑结构 D.数据元素之间的关系 1.2数据的逻辑结构是指: A. 数据所占的存储空间量 B.各数据元素之间的逻辑关系 C. 数据在计算机中顺序或链接的存储方式 D. 存储在内存或外存中的数据 1.3在下列的叙述中,正确的是: A.数据的逻辑结构是指数据的各数据项之间的逻辑关系。 B.数据的物理结构是指数据在计算机内的实际存储形式。 C.在顺序存储结构中,数据元素之间的关系是显示体现的。 D.链接存储结构是通过结点的存储位置相邻来体现数据元素之间的关系。 填空题: 1.4 内容。 1.5 1.6 1.7 1.8表示关系。 1.9 1.10 简答题: 1.11数据结构研究的三方面内容之间有什么联系和区别? 数据结构研究的三方面内容包括: 数据的逻辑结构、存储结构和运算。数据的逻辑结构是数学模型,存储结构是指逻辑结构到存储区域的映射,运算是定义在逻辑结构上,实现在存储结构上。 1.12简述数据结构中讨论的三种经典结构的逻辑特征是什么? 三种经典结构:线性表、树和图。逻辑特征分别为: (1)线性表:一对一。有且仅有一个开始结点和一个终端结点,其余的内部结点都有且仅有一个前趋结点和一个后继结点。 (2)树:一对多。有且仅有一个开始结点,可有若干个终端结点,其余的内部结点都有且仅有一个前趋结点,可以有若干个后继结点。 (3)图:多对多。可有若干个开始结点和终端结点,其余的内部结点可以有若干个前趋结点和若干个后继结点。 1.13简述各种常用存储方法的基本思想。 各种方法的基本思想: 顺序存储:逻辑上相邻的数据元素存储在物理位置上相邻的存储单元里。 链接存储:通过附加指针域表示数据元素之间的关系。 索引存储:除了存储数据元素,还要建立附加的索引表来标识数据元素的地址。 散列存储:根据关键字直接计算出该结点的存储地址,通常称为关键字-地址转换法。

数据结构试题及答案

一、判断题: 1、线性表的逻辑顺序与物理顺序总是一致的。( ) 2、线性表的顺序存储表示优于链式存储表示。( ) 3、线性表若采用链式存储表示时所有结点之间的存储单元地址可连续可不连续。( ) 4、二维数组是其数组元素为线性表的线性表。( ) 5、每种数据结构都应具备三种基本运算:插入、删除和搜索。( ) 6、数据结构概念包括数据之间的逻辑结构,数据在计算机中的存储方式和数据的运算三个 方面。( ) 7、线性表中的每个结点最多只有一个前驱和一个后继。() 8、线性的数据结构可以顺序存储,也可以链接存储。非线性的数据结构只能链接存储。() 9、栈和队列逻辑上都是线性表。() 10、单链表从任何一个结点出发,都能访问到所有结点() 11、删除二叉排序树中一个结点,再重新插入上去,一定能得到原来的二叉排序树。() 12、快速排序是排序算法中最快的一种。() 13、多维数组是向量的推广。() 14、一般树和二叉树的结点数目都可以为0。() 15、直接选择排序是一种不稳定的排序方法。() 16、98、对一个堆按层次遍历,不一定能得到一个有序序列。() 17、在只有度为0和度为k的结点的k叉树中,设度为0的结点有n0个,度为k的结点有nk个,则有n0=nk+1。() 18、折半搜索只适用与有序表,包括有序的顺序表和有序的链表。() 19、堆栈在数据中的存储原则是先进先出。() 20、队列在数据中的存储原则是后进先出。() 21、用相邻矩阵表示图所用的存储空间大小与图的边数成正比。() 22、哈夫曼树一定是满二叉树。() 23、程序是用计算机语言表述的算法。() 24、线性表的顺序存储结构是通过数据元素的存储地址直接反映数据元素的逻辑关系。() 25、用一组地址连续的存储单元存放的元素一定构成线性表。() 26、堆栈、队列和数组的逻辑结构都是线性表结构。() 27、给定一组权值,可以唯一构造出一棵哈夫曼树。() 28、只有在初始数据为逆序时,冒泡排序所执行的比较次数最多。()

数据的存储结构是指

(1)数据的存储结构是指 (A)存储在外存中的数据(B)数据所占的存储空间量 (C)数据在计算机中的顺序存储方式(D)数据的逻辑结构在计算机中的表示 (2)下列关于栈的描述中错误的是 (A)栈是先进后出的先性表 (B)栈只能顺序存储 (C)栈具有记忆作用 (D)对栈的插入和删除操作中,不需要改变栈底指针 (3)对于长度为N的线性表,在最坏的情况下,下列各排序法所对应的比较次数中正确的是 (A)冒泡排序为N/2 (B)冒泡排序为N (C)快速排序为N (D)快速排序为N(N-1)/2 (4)对长度为N的线性表进行顺序查找,在最坏的情况下所需要的比较次数为 (A)log2n (B)n/2 (C)n (D)n+1 (5)数字字符0的ASCII值为48,若有以下程序main() { char a='1',b='2'; printf("%c,",b++); printf("%d\n",b-a); } 程序运行后的输出结果是 (A)3,2 (B)50,2 (C)2,2 (D)2,50 1.D 2.B 3.D 4.C 5.C (1)用二维表数据来表示实体及实体之间联系的数据模型称为__。 (2)在Visual FoxPro中说明数组后,数组的每个元素在未赋值之前的默认值是__。(3)可以在项目管理器的__选项卡下建立命令文件。 (4)在Visual FoxPro中数据库文件的扩展名是__,数据库表文件的扩展名是__。(5)打开数据库设计器的命令是__DA TABASE。 (6)SQL插入记录的命令是INSERT,删除记录的命令是__,修改记录的命令是__。 (7)在SQL的嵌套查询中,量词ANY和__是同义词。在SQL查询时,使用子句指__出的是查询条件。 (8)从职工数据库中计算工资合计的SQL语句是

数据结构实验一_顺序表的基本操作实验报告

实验一顺序表的基本操作 一、实验目的 掌握线性表的顺序表基本操作:建立、插入、删除、查找、合并、打印等运算。 二、实验要求包含有头文件和main函数; 1.格式正确,语句采用缩进格式; 2.设计子函数实现题目要求的功能; 3.编译、连接通过,熟练使用命令键; 4.运行结果正确,输入输出有提示,格式美观。 三、实验设备、材料和工具 1.奔腾2计算机或以上机型 2.turboc2,win-tc 四、实验内容和步骤 1. 建立一个含n个数据元素的顺序表并输出该表中各元素的值及顺序表的长度。 2. 往该顺序表中第i位置插入一个值为x的数据元素。 3. 从该顺序表中第j位置删除一个数据元素,由y返回。 4. 从该顺序表中查找一个值为e的数据元素,若找到则返回该数据元素的位置,否则返回“没有找到”。 五、程序 #include #include #define list_init_size 10 #define increment 2

typedef struct { int *elem; int length,listsize; }sqlist; //类型定义 void initlist_sq(sqlist &L) //初始化顺序表 { } void output(sqlist L) //输出顺序表 { } void insertlist(sqlist &L,int i, int x) //顺序表中插入x { } void deletelist(sqlist &L,int j, int y) //顺序表中删除y { } int locateelem(sqlist &L,int e) //顺序表中查找e { } void main() { } 【运行结果】 void initlist_sq(sqlist &L) //初始化顺序表 { L.elem=(int*)malloc(LIST_INIT_SIZE*sizeof(int)); if(!L.elem) exit (OVERFLOW);

相关文档
最新文档