💡 【教材】 ▲05 数组和广义表

This commit is contained in:
康建伟
2018-01-06 21:30:45 +08:00
parent ce7d108fa3
commit bc574933a3
21 changed files with 3787 additions and 0 deletions

View File

@@ -0,0 +1,73 @@
/**********************************************
* *
* 文件夹: ▲05 数组和广义表\01 SequenceArray *
* *
* 内 容: 数组相关函数测试 *
* *
**********************************************/
#include <stdio.h>
#include "SequenceArray.c" //**▲05 数组和广义表**//
/* 以二维数组为例测试 */
int main(int argc, char **argv)
{
Array A;
printf("▼1\n▲函数 InitArray 测试(以二维数组为例)...\n");//1.函数InitArray测试
{
printf("初始化一个 2 行 3 列的二维数组 A ...\n");
InitArray(&A, 2, 2, 3);
printf("\n");
}
PressEnter;
printf("▼5\n▲函数 AssignArray 测试...\n"); //5.函数AssignArray测试
{
int i, j;
AElemType_Sq e = 0;
for(i=0; i<A.bounds[0]; i++)
{
for(j=0; j<A.bounds[1]; j++)
{
printf("赋值A[%d][%d] = %d\n", i, j, ++e);
AssignArray(&A, e, i, j);
}
}
printf("\n");
}
PressEnter;
printf("▼6\n▲函数 ArrayPrint 测试...\n"); //6.函数ArrayPrint测试
{
printf(" A = ");
ArrayPrint(A);
printf("\n\n");
}
PressEnter;
printf("▼3、4\n▲函数 LocateArray、ValueArray 测试...\n"); //3、4.函数LocateArray、ValueArray测试
{
AElemType_Sq x;
printf("获取 A 中下标为 (1,1) 的元素的值Locate 用于求出 A[1][1] 的相对位置...\n");
ValueArray(A, &x, 1, 1);
printf(" A[1][1] = %d\n", x);
printf("\n");
}
PressEnter;
printf("▼2\n▲函数 DestroyArray 测试...\n"); //2.函数DestroyArray测试
{
printf("销毁 A 前:");
A.dim!=0 ? printf(" A 存在!\n") : printf(" A 不存在!!\n");
DestroyArray(&A);
printf("销毁 A 后:");
A.dim!=0 ? printf(" A 存在!\n") : printf(" A 不存在!!\n");
printf("\n");
}
PressEnter;
return 0;
}

View File

@@ -0,0 +1,142 @@
/**********************************************
* *
* 文件夹: ▲05 数组和广义表\01 SequenceArray *
* *
* 文件名: SequenceArray.c *
* *
**********************************************/
#ifndef SEQUENCEARRAY_C
#define SEQUENCEARRAY_C
#include "SequenceArray.h" //**▲05 数组和广义表**//
Status InitArray(Array *A, int dim, ...)
{
int elemtotal; //统计数组中总元素个数
va_list ap; //ap存放可变参数表信息
int i;
if(dim<1 || dim>MAX_ARRAY_DIM) //数组维数有限制
return ERROR;
A->dim = dim; //初始化数组维度
A->bounds = (int*)malloc(dim*sizeof(int)); //初始化数组维度信息表
if(!A->bounds)
return OVERFLOW;
elemtotal = 1;
va_start(ap, dim); //使ap指向第一个可变参数dim相当于起始标识
for(i=0; i<dim; i++)
{
A->bounds[i] = va_arg(ap, int); //获取数组行、列信息
if(A->bounds[i]<=0)
return UNDERFLOW;
elemtotal *= A->bounds[i];
}
va_end(ap); //置空ap
A->base = (AElemType_Sq*)malloc(elemtotal*sizeof(AElemType_Sq));
if(!A->base) //初始化数组空间
return OVERFLOW;
A->constants = (int*)malloc(dim*sizeof(int)); //初始化数组映像函数常量信息表
if(!A->constants)
return OVERFLOW;
A->constants[dim-1] = 1;
for(i=dim-2; i>=0; i--) //假设数组维度为2则constants存储移动每一行、每一列所需跨越的元素个数
A->constants[i] = A->bounds[i+1] * A->constants[i+1];
return OK;
}
Status DestroyArray(Array *A)
{
if(!A->base)
return ERROR;
free(A->base);
A->base = NULL;
if(!A->bounds)
return ERROR;
free(A->bounds);
A->bounds = NULL;
if(!A->constants)
return ERROR;
free(A->constants);
A->constants = NULL;
A->dim = 0;
return OK;
}
Status LocateArray(Array A, va_list ap, int *off)
{
int i, ind;
*off = 0;
for(i=0; i<A.dim; i++)
{
ind = va_arg(ap, int);
if(ind<0 || ind>=A.bounds[i]) //保证下标不越界
return OVERFLOW;
*off += A.constants[i] * ind; //某个维度的单位元素个数*需要跨过的单位
}
return OK;
}
Status ValueArray(Array A, AElemType_Sq *e, ...)
{
va_list ap;
Status result;
int off;
va_start(ap, *e);
result = LocateArray(A, ap, &off);
if(result==OVERFLOW)
return result;
*e = *(A.base + off);
return OK;
}
Status AssignArray(Array *A, AElemType_Sq e, ...)
{
va_list ap;
Status result;
int off;
va_start(ap, e);
result = LocateArray(*A, ap, &off);
if(result==OVERFLOW)
return result;
*(A->base+off) = e;
return OK;
}
void ArrayPrint(Array A)
{
int i, j;
for(i=0,j=1; i<A.dim; i++)
j *= A.bounds[i];
for(i=0; i<j; i++)
printf("%d ", A.base[i]);
}
#endif

View File

@@ -0,0 +1,63 @@
/**********************************************
* *
* 文件夹: ▲05 数组和广义表\01 SequenceArray *
* *
* 文件名: SequenceArray.h *
* *
* 内 容: 数组相关操作列表 *
* *
**********************************************/
#ifndef SEQUENCEARRAY_H
#define SEQUENCEARRAY_H
#include <stdio.h>
#include <stdlib.h> //提供malloc、realloc、free、exit原型
#include <stdarg.h> //提供宏va_start、va_arg、va_end
#include "../../▲01 绪论/Status.h" //**▲01 绪论**//
/* 宏定义 */
#define MAX_ARRAY_DIM 8 //数组的最大维度为8
/* 数组类型定义 */
typedef int AElemType_Sq;
typedef struct //数组的顺序存储表示
{
AElemType_Sq *base; //数组元素基址(存放数组元素)
int dim; //数组维数
int *bounds; //数组维界基址(存放数组行、列信息)
int *constants; //数组映像函数常量基址(存储跨越某个维度时需要越过的元素个数)
}Array;
/* 数组函数列表 */
Status InitArray(Array *A, int dim, ...);
/*━━━━━━━━━━━━━━┓
┃(01)初始化维数为dim的数组。 ┃
┗━━━━━━━━━━━━━━*/
Status DestroyArray(Array *A);
/*━━━━━━━┓
┃(02)销毁数组。┃
┗━━━━━━━*/
Status LocateArray(Array A, va_list ap, int *off);
/*━━━━━━━━━━━━━━━━━━━━┓
┃(03)求出ap指示的值在数组A中的相对位置。 ┃
┗━━━━━━━━━━━━━━━━━━━━*/
Status ValueArray(Array A, AElemType_Sq *e, ...);
/*━━━━━━━━━━━━━━━━━┓
┃(04)取值可变参数是dim个下标值。 ┃
┗━━━━━━━━━━━━━━━━━*/
Status AssignArray(Array *A, AElemType_Sq e, ...);
/*━━━━━━━━━━━━━━━━━┓
┃(05)赋值可变参数是dim个下标值。 ┃
┗━━━━━━━━━━━━━━━━━*/
void ArrayPrint(Array A);
/*━━━━━━━━━━━━━━┓
┃(06)按行依次输出数组中内容。┃
┗━━━━━━━━━━━━━━*/
#endif

View File

@@ -0,0 +1,9 @@
行数5
列数5
非零元个数10
三元组:(1,2,1),(1,4,5),(2,3,-3),(2,5,2),(3,1,2),(3,2,3),(3,3,4),(4,4,2),(5,1,3),(5,2,-1)
行数5
列数5
非零元个数8
三元组:(1,1,-3)(1,3,2)(2,4,-1)(3,2,4)(4,1,6)(4,5,5)(5,1,3)(5,3,2)

View File

@@ -0,0 +1,117 @@
/***************************************************
* *
* 文件夹: ▲05 数组和广义表\02 TripleSparseMatrix *
* *
* 内 容: 三元组顺序表(稀疏矩阵)相关函数测试 *
* *
***************************************************/
#include <stdio.h>
#include "TripleSparseMatrix.c" //**▲05 数组和广义表**//
int main(int argc, char **argv)
{
TSMatrix M, N;
printf("▼1\n▲函数 CreateSMatrix_T 测试...\n"); //1.函数CreateSMatrix_T测试
{
FILE *fp; //作为输入源
printf("创建两个稀疏矩阵 M、N ...\n");
fp = fopen("TestData_TSMatrix.txt", "r");
CreateSMatrix_T(fp, 2, &M, &N);
fclose(fp);
printf("\n");
}
PressEnter;
printf("▼3\n▲函数 PrintSMatrix_T 测试...\n"); //3.函数PrintSMatrix_T测试
{
printf(" M = \n");
PrintSMatrix_T(M);
printf(" N = \n");
PrintSMatrix_T(N);
printf("\n");
}
PressEnter;
printf("▼4\n▲函数 CopySMatrix_T 测试...\n"); //4.函数CopySMatrix_T测试
{
TSMatrix Tmp;
printf("复制 M 到 Tmp...\n");
CopySMatrix_T(M, &Tmp);
printf(" Tmp = \n");
PrintSMatrix_T(Tmp);
printf("\n");
}
PressEnter;
printf("▼5\n▲函数 AddSMatri_T 测试...\n"); //5.函数AddSMatri_T测试
{
TSMatrix Q1;
AddSMatri_T(M, N, &Q1);
printf(" Q1 = M + N = \n");
PrintSMatrix_T(Q1);
printf("\n");
}
PressEnter;
printf("▼6\n▲函数 SubSMatrix_T 测试...\n"); //6.函数SubSMatrix_T测试
{
TSMatrix Q2;
SubSMatrix_T(M, N, &Q2);
printf(" Q2 = M - N = \n");
PrintSMatrix_T(Q2);
printf("\n");
}
PressEnter;
printf("▼7\n▲函数 MultSMatrix_T 测试...\n"); //7.函数MultSMatrix_T测试
{
TSMatrix Q3;
MultSMatrix_T(M, N, &Q3);
printf(" Q3 = M * N = \n");
PrintSMatrix_T(Q3);
printf("\n");
}
PressEnter;
printf("▼8\n▲函数 TransposeSMatrix_T 测试...\n"); //8.函数TransposeSMatrix_T测试
{
TSMatrix T1;
TransposeSMatrix_T(M, &T1);
printf(" T1 = M(T) = \n");
PrintSMatrix_T(T1);
printf("\n");
}
PressEnter;
printf("▼9\n▲函数 FastTransposeSMatrix_T 测试...\n"); //9.函数FastTransposeSMatrix_T测试
{
TSMatrix T2;
FastTransposeSMatrix_T(M, &T2);
printf(" T2 = M(T) = \n");
PrintSMatrix_T(T2);
printf("\n");
}
PressEnter;
printf("▼2\n▲函数 DestroySMatrix_T 测试...\n"); //2.函数DestroySMatrix_T测试
{
printf("销毁 M 前:");
!M.mu && !M.nu && !M.tu ? printf(" M 不存在!!\n") : printf(" M 存在!\n");
DestroySMatrix_T(&M);
printf("销毁 M 后:");
!M.mu && !M.nu && !M.tu ? printf(" M 不存在!!\n") : printf(" M 存在!\n");
printf("\n");
}
PressEnter;
return 0;
}

View File

@@ -0,0 +1,372 @@
/***************************************************
* *
* 文件夹: ▲05 数组和广义表\02 TripleSparseMatrix *
* *
* 文件名: TripleSparseMatrix.c *
* *
* 算 法: 5.1、5.2 *
* *
***************************************************/
#ifndef TRIPLESPARSEMATRIX_C
#define TRIPLESPARSEMATRIX_C
#include "TripleSparseMatrix.h" //**▲05 数组和广义表**//
Status CreateSMatrix_T(FILE *fp, int n, ...)
{
int count, k;
TSMatrix *M;
if(n<1)
return ERROR;
va_list ap;
va_start(ap, n);
for(count=1; count<=n; count++)
{
M = va_arg(ap, TSMatrix*);
Scanf(fp, "%d%d%d", &((*M).mu), &((*M).nu), &((*M).tu));
for(k=1; k<=(*M).tu; k++)
Scanf(fp, "%d%d%d", &((*M).data[k].i), &((*M).data[k].j), &((*M).data[k].e));
}
va_end(ap);
return OK;
}
void DestroySMatrix_T(TSMatrix *M)
{
(*M).mu = 0;
(*M).nu = 0;
(*M).tu = 0;
}
void PrintSMatrix_T(TSMatrix M)
{
int r, c;
int k = 1;
for(r=1; r<=M.mu; r++)
{
for(c=1; c<=M.nu; c++)
{
if(r==M.data[k].i && c==M.data[k].j)
{
printf("%3d ", M.data[k].e);
k++;
}
else
printf(" 0 ");
}
printf("\n");
}
}
void CopySMatrix_T(TSMatrix M, TSMatrix *T)
{
(*T) = M; //结构可以直接复制
}
Status AddSMatri_T(TSMatrix M, TSMatrix N, TSMatrix *Q)
{
int m, n, k;
if(M.mu!=N.mu || M.nu!=N.nu)
{
printf("两矩阵不能相加!!\n");
return ERROR;
}
Q->mu = M.mu;
Q->nu = M.nu;
Q->tu = 0;
m = n = k = 1;
while(m<=M.tu && n<=N.tu) //依次遍历M与N的三元组
{
if(M.data[m].i<N.data[n].i)
{
Q->data[k] = M.data[m];
m++;
}
else if(M.data[m].i>N.data[n].i)
{
Q->data[k] = N.data[n];
n++;
}
else //M.data[m].i==N.data[n].i
{
if(M.data[m].j<N.data[n].j)
{
Q->data[k] = M.data[m];
m++;
}
else if(M.data[m].j>N.data[n].j)
{
Q->data[k] = N.data[n];
n++;
}
else //M.data[m].j==N.data[n].j
{
if(M.data[m].e+N.data[n].e)
{
Q->data[k].i = M.data[m].i;
Q->data[k].j = M.data[m].j;
Q->data[k].e = M.data[m].e + N.data[n].e;
m++;
n++;
}
else
{
m++;
n++;
continue;
}
}
}
k++;
Q->tu++;
}
while(m<=M.tu)
{
Q->data[k] = M.data[m];
m++;
k++;
Q->tu++;
}
while(n<=N.tu)
{
Q->data[k] = N.data[n];
n++;
k++;
Q->tu++;
}
return OK;
}
Status SubSMatrix_T(TSMatrix M, TSMatrix N, TSMatrix *Q)
{
int m, n, k;
if(M.mu!=N.mu || M.nu!=N.nu)
{
printf("两矩阵不能相减!!\n");
return ERROR;
}
Q->mu = M.mu;
Q->nu = M.nu;
Q->tu = 0;
m = n = k = 1;
while(m<=M.tu && n<=N.tu)
{
if(M.data[m].i<N.data[n].i)
{
Q->data[k] = M.data[m];
m++;
}
else if(M.data[m].i>N.data[n].i)
{
Q->data[k].i = N.data[n].i;
Q->data[k].j = N.data[n].j;
Q->data[k].e = -N.data[n].e;
n++;
}
else //M.data[m].i==N.data[n].i
{
if(M.data[m].j<N.data[n].j)
{
Q->data[k] = M.data[m];
m++;
}
else if(M.data[m].j>N.data[n].j)
{
Q->data[k].i = N.data[n].i;
Q->data[k].j = N.data[n].j;
Q->data[k].e = -N.data[n].e;
n++;
}
else //M.data[m].j==N.data[n].j
{
if(M.data[m].e-N.data[n].e)
{
Q->data[k].i = M.data[m].i;
Q->data[k].j = M.data[m].j;
Q->data[k].e = M.data[m].e - N.data[n].e;
m++;
n++;
}
else
{
m++;
n++;
continue;
}
}
}
k++;
Q->tu++;
}
while(m<=M.tu)
{
Q->data[k] = M.data[m];
m++;
k++;
Q->tu++;
}
while(n<=N.tu)
{
Q->data[k].i = N.data[n].i;
Q->data[k].j = N.data[n].j;
Q->data[k].e = -N.data[n].e;;
n++;
k++;
Q->tu++;
}
return OK;
}
Status MultSMatrix_T(TSMatrix M, TSMatrix N, TSMatrix *Q)
{
int m, n, i, j, k;
MElemType_TSq c, c1, c2;
if(M.nu!=N.mu) //M列数等于N行数
{
printf("两矩阵不能相乘!!\n");
return ERROR;
}
Q->mu = M.mu; //Q初始化
Q->nu = N.nu;
Q->tu = 0;
if(M.tu*N.tu) //Q是非零矩阵
{
for(i=1; i<=M.mu; i++) //传统矩阵乘法
{
for(j=1; j<=N.nu; j++)
{
c = 0;
for(k=1; k<=M.nu; k++)
{
c1 = 0;
for(m=1; m<=M.tu; m++) //依次寻找位于指定位置的M三元组
{
if(M.data[m].i==i && M.data[m].j==k)
{
c1 = M.data[m].e;
break;
}
}
c2 = 0;
for(n=1; n<=N.tu; n++) //依次寻找位于指定位置的N三元组
{
if(N.data[n].i==k && N.data[n].j==j)
{
c2 = N.data[n].e;
break;
}
}
if(c1 && c2)
c += c1 * c2;
}
if(c)
{
Q->tu++;
Q->data[Q->tu].i = i;
Q->data[Q->tu].j = j;
Q->data[Q->tu].e = c;
}
}
}
}
return OK;
}
/*════╗
║ 算法5.1║
╚════*/
void TransposeSMatrix_T(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; //q用于T中非零元计数
for(col=1; col<=M.nu; ++col) //col代表M的列T的行
{
for(p=1; p<=M.tu; ++p) //p用于M中非零元计数
{
if(M.data[p].j==col)
{
T->data[q].i = M.data[p].j; //M的列变为T的行
T->data[q].j = M.data[p].i; //M的行变为T的列
T->data[q].e = M.data[p].e; //每个三元组值不变
++q;
}
}
}
}
}
/*════╗
║ 算法5.2║
╚════*/
void FastTransposeSMatrix_T(TSMatrix M, TSMatrix *T)
{
int col, t, p, q;
int num[M.nu]; //num[col]表示M第col列中非零元的个数
int copt[M.nu]; //copt[col]表示M第col列第一个非零元在T->data中恰当的位置
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; //初始化数组num
for(t=1; t<=M.tu; ++t) //t遍历M中三元组
num[M.data[t].j]++; //统计M中每列非零元个数
copt[1] = 1;
for(col=2; col<=M.nu; ++col)
copt[col] = copt[col-1] + num[col-1];
for(p=1; p<=M.tu; ++p) //依次扫描M中的三元组
{
col = M.data[p].j; //col为M中第p个三元组中元素的列
q = copt[col]; //q为当前三元组元素在T中应放置的位置
T->data[q].i = M.data[p].j;
T->data[q].j = M.data[p].i;
T->data[q].e = M.data[p].e;
++copt[col]; //再遇到此列元素时位置增一
}
}
}
#endif

View File

@@ -0,0 +1,81 @@
/***************************************************
* *
* 文件夹: ▲05 数组和广义表\02 TripleSparseMatrix *
* *
* 文件名: TripleSparseMatrix.h *
* *
* 内 容: 三元组顺序表(稀疏矩阵)相关操作列表 *
* *
***************************************************/
#ifndef TRIPLESPARSEMATRIX_H
#define TRIPLESPARSEMATRIX_H
#include <stdio.h>
#include <stdarg.h> //提供宏va_list、va_start、va_arg、va_end
#include "../../▲01 绪论/Status.h" //**▲01 绪论**//
#include "../../▲01 绪论/Scanf.c" //**▲01 绪论**//
/* 宏定义 */
#define MAXSIZE 400 //假设非零元个数的最大值为400
/* 三元组稀疏矩阵类型定义 */
typedef int MElemType_TSq;
typedef struct
{
int i, j; //该非零元的行下标和列下标
MElemType_TSq e;
}Triple;
typedef struct
{
Triple data[MAXSIZE+1]; //非零元三元组表data[0]未用
int mu, nu, tu; //矩阵的行数、列数和非零元个数
}TSMatrix;
/* 三元组顺序表(稀疏矩阵)函数列表 */
Status CreateSMatrix_T(FILE *fp, int n, ...);
/*━━━━━━━━━┓
┃(01)创建n个矩阵。 ┃
┗━━━━━━━━━*/
void DestroySMatrix_T(TSMatrix *M);
/*━━━━━━━┓
┃(02)销毁矩阵。┃
┗━━━━━━━*/
void PrintSMatrix_T(TSMatrix M);
/*━━━━━━━┓
┃(03)输出矩阵。┃
┗━━━━━━━*/
void CopySMatrix_T(TSMatrix M, TSMatrix *T);
/*━━━━━━━━┓
┃(04)矩阵的复制。┃
┗━━━━━━━━*/
Status AddSMatri_T(TSMatrix M, TSMatrix N, TSMatrix *Q);
/*━━━━━━━━┓
┃(05)Q = M + N。 ┃
┗━━━━━━━━*/
Status SubSMatrix_T(TSMatrix M, TSMatrix N, TSMatrix *Q);
/*━━━━━━━━┓
┃(06)Q = M - N。 ┃
┗━━━━━━━━*/
Status MultSMatrix_T(TSMatrix M, TSMatrix N, TSMatrix *Q);
/*━━━━━━━━┓
┃(07)Q = M * N。 ┃
┗━━━━━━━━*/
void TransposeSMatrix_T(TSMatrix M, TSMatrix *T);
/*━━━━━━━━━━━━┓
┃(08)算法5.1:矩阵转置。 ┃
┗━━━━━━━━━━━━*/
void FastTransposeSMatrix_T(TSMatrix M, TSMatrix *T);
/*━━━━━━━━━━━━━━┓
┃(09)算法5.2:矩阵快速转置。 ┃
┗━━━━━━━━━━━━━━*/
#endif

View File

@@ -0,0 +1,118 @@
/******************************************************
* *
* 文件夹: ▲05 数组和广义表\03 RowLinkSparseMatrix *
* *
* 内 容: 行逻辑链接的顺序表(稀疏矩阵)相关函数测试 *
* *
******************************************************/
#include <stdio.h>
#include "RowLinkSparseMatrix.c" //**05 数组和广义表**//
int main(int argc, char **argv)
{
RLSMatrix M, N;
printf("▼1\n▲函数 CreateSMatrix_RL 测试...\n"); //1.函数CreateSMatrix_RL测试
{
FILE *fp; //作为输入源
printf("创建两个稀疏矩阵 M、N ...\n");
fp = fopen("TestData_RLSMatrix.txt", "r");
CreateSMatrix_RL(fp, 2, &M, &N);
fclose(fp);
printf("\n");
}
PressEnter;
printf("▼3\n▲函数 PrintSMatrix_RL 测试...\n"); //3.函数PrintSMatrix_RL测试
{
printf(" M = \n");
PrintSMatrix_RL(M);
printf("\n");
printf(" N = \n");
PrintSMatrix_RL(N);
printf("\n");
}
PressEnter;
printf("▼4\n▲函数 CopySMatrix_RL 测试...\n"); //4.函数CopySMatrix_RL测试
{
RLSMatrix Tmp;
printf("复制 M 到 Tmp...\n");
CopySMatrix_RL(M, &Tmp);
printf(" Tmp = \n");
PrintSMatrix_RL(Tmp);
printf("\n");
}
PressEnter;
printf("▼5\n▲函数 AddSMatri_RL 测试...\n"); //5.函数AddSMatri_RL测试
{
RLSMatrix Q1;
AddSMatri_RL(M, N, &Q1);
printf(" Q1 = M + N = \n");
PrintSMatrix_RL(Q1);
printf("\n");
}
PressEnter;
printf("▼6\n▲函数 SubtSMatrix_RL 测试...\n"); //6.函数SubtSMatrix_RL测试
{
RLSMatrix Q2;
SubSMatrix_RL(M, N, &Q2);
printf(" Q2 = M - N = \n");
PrintSMatrix_RL(Q2);
printf("\n");
}
PressEnter;
printf("▼7\n▲函数 MultSMatrix_RL 测试...\n"); //7.函数MultSMatrix_RL测试
{
RLSMatrix Q3;
MultSMatrix_RL(M, N, &Q3);
printf(" Q3 = M * N = \n");
PrintSMatrix_RL(Q3);
printf("\n");
}
PressEnter;
printf("▼8\n▲函数 TransposeSMatrix_RL 测试...\n"); //8.函数TransposeSMatrix_RL测试
{
RLSMatrix T1;
TransposeSMatrix_RL(M, &T1);
printf(" T1 = M(T) = \n");
PrintSMatrix_RL(T1);
printf("\n");
}
PressEnter;
printf("▼9\n▲函数 FastTransposeSMatrix_RL 测试...\n"); //9.函数FastTransposeSMatrix_RL测试
{
RLSMatrix T2;
FastTransposeSMatrix_RL(M, &T2);
printf(" T2 = M(T) = \n");
PrintSMatrix_RL(T2);
printf("\n");
}
PressEnter;
printf("▼2\n▲函数 DestroySMatrix_RL 测试...\n"); //2.函数DestroySMatrix_RL测试
{
printf("销毁 M 前:");
!M.mu && !M.nu && !M.tu ? printf(" M 不存在!!\n") : printf(" M 存在!\n");
DestroySMatrix_RL(&M);
printf("销毁 M 后:");
!M.mu && !M.nu && !M.tu ? printf(" M 不存在!!\n") : printf(" M 存在!\n");
printf("\n");
}
PressEnter;
return 0;
}

View File

@@ -0,0 +1,83 @@
/******************************************************
* *
* 文件夹: ▲05 数组和广义表\03 RowLinkSparseMatrix *
* *
* 文件名: RowLinkSparseMatrix.h *
* *
* 内 容: 行逻辑链接的顺序表(稀疏矩阵)相关操作列表 *
* *
******************************************************/
#ifndef ROWLINKSPARSEMATRIX_H
#define ROWLINKSPARSEMATRIX_H
#include <stdio.h>
#include <stdarg.h> //提供宏va_list、va_start、va_arg、va_end
#include "../../▲01 绪论/Status.h" //**▲01 绪论**//
#include "../../▲01 绪论/Scanf.c" //**▲01 绪论**//
/* 宏定义 */
#define MAXSIZE 400 //假设非零元个数的最大值为400
#define MAXRC 20 //各行元素个数的最大值
/* 行逻辑链接的稀疏矩阵类型定义 */
typedef int MElemType_RLSq;
typedef struct
{
int i, j; //该非零元的行下标和列下标
MElemType_RLSq e;
}Triple;
typedef struct
{
Triple data[MAXSIZE+1]; //非零元三元组表data[0]未用
int rpos[MAXRC+1]; //各行第一个非零元在三元组表中的位置表
int mu, nu, tu; //矩阵的行数、列数和非零元个数
}RLSMatrix;
/* 行逻辑链接的顺序表(稀疏矩阵)基础操作 */
Status CreateSMatrix_RL(FILE *fp, int n, ...);
/*━━━━━━━━┓
┃(01)创建矩阵M。 ┃
┗━━━━━━━━*/
void DestroySMatrix_RL(RLSMatrix *M);
/*━━━━━━━┓
┃(02)销毁矩阵。┃
┗━━━━━━━*/
void PrintSMatrix_RL(RLSMatrix M);
/*━━━━━━━┓
┃(03)输出矩阵。┃
┗━━━━━━━*/
void CopySMatrix_RL(RLSMatrix M, RLSMatrix *T);
/*━━━━━━━━┓
┃(04)矩阵的复制。┃
┗━━━━━━━━*/
Status AddSMatri_RL(RLSMatrix M, RLSMatrix N, RLSMatrix *Q);
/*━━━━━━━━┓
┃(05)Q = M + N。 ┃
┗━━━━━━━━*/
Status SubSMatrix_RL(RLSMatrix M, RLSMatrix N, RLSMatrix *Q);
/*━━━━━━━━┓
┃(06)Q = M - N。 ┃
┗━━━━━━━━*/
Status MultSMatrix_RL(RLSMatrix M, RLSMatrix N, RLSMatrix *Q);
/*━━━━━━━━━━━━┓
┃(07)算法5.3Q = M * N。┃
┗━━━━━━━━━━━━*/
void TransposeSMatrix_RL(RLSMatrix M, RLSMatrix *T);
/*━━━━━━━┓
┃(08)矩阵转置。┃
┗━━━━━━━*/
void FastTransposeSMatrix_RL(RLSMatrix M, RLSMatrix *T);
/*━━━━━━━━━┓
┃(09)矩阵快速转置。┃
┗━━━━━━━━━*/
#endif

View File

@@ -0,0 +1,9 @@
行数5
列数5
非零元个数10
三元组:(1,2,1),(1,4,5),(2,3,-3),(2,5,2),(3,1,2),(3,2,3),(3,3,4),(4,4,2),(5,1,3),(5,2,-1)
行数5
列数5
非零元个数8
三元组:(1,1,-3)(1,3,2)(2,4,-1)(3,2,4)(4,1,6)(4,5,5)(5,1,3)(5,3,2)

View File

@@ -0,0 +1,105 @@
/********************************************
* *
* 文件夹: ▲05 数组和广义表\04 CrossList *
* *
* 内 容: 十字链表(稀疏矩阵)相关函数测试 *
* *
********************************************/
#include <stdio.h>
#include "CrossList.c" //**▲05 数组和广义表**//
int main(int argc, char **argv)
{
CrossList M, N;
printf("▼1\n▲函数 CreateSMatrix_OL 测试...\n"); //1.函数CreateSMatrix_OL测试
{
FILE *fp; //作为输入源
printf("创建两个稀疏矩阵 M、N ...\n");
fp = fopen("TestData_CrossList.txt", "r");
CreateSMatrix_OL(fp, 2, &M, &N);
fclose(fp);
printf("\n");
}
PressEnter;
printf("▼3\n▲函数 PrintSMatrix_OL 测试...\n"); //3.函数PrintSMatrix_OL测试
{
printf(" M = \n");
PrintSMatrix_OL(M);
printf(" N = \n");
PrintSMatrix_OL(N);
printf("\n");
}
PressEnter;
printf("▼4\n▲函数 CopySMatrix_OL 测试...\n"); //4.函数CopySMatrix_OL测试
{
CrossList Tmp;
CopySMatrix_OL(M, &Tmp);
printf("Tmp = \n");
PrintSMatrix_OL(Tmp);
printf("\n");
}
PressEnter;
printf("▼5\n▲函数 AddSMatri_OL 测试...\n"); //5.函数AddSMatri_OL测试
{
CrossList Q1;
AddSMatri_OL(M, N, &Q1);
printf(" Q1 = M + N = \n");
PrintSMatrix_OL(Q1);
printf("\n");
}
PressEnter;
printf("▼6\n▲函数 SubtSMatrix_OL 测试...\n"); //6.函数SubtSMatrix_OL测试
{
CrossList Q2;
SubSMatrix_OL(M, N, &Q2);
printf(" Q2 = M - N = \n");
PrintSMatrix_OL(Q2);
printf("\n");
}
PressEnter;
printf("▼7\n▲函数 MultSMatrix_OL 测试...\n"); //7.函数MultSMatrix_OL测试
{
CrossList Q3;
MultSMatrix_OL(M, N, &Q3);
printf(" Q3 = M * N = \n");
PrintSMatrix_OL(Q3);
printf("\n");
}
PressEnter;
printf("▼8\n▲函数 TransposeSMatrix_OL 测试...\n"); //8.函数TransposeSMatrix_OL测试
{
CrossList T;
TransposeSMatrix_OL(M, &T);
printf(" T = M(T) = \n");
PrintSMatrix_OL(T);
printf("\n");
}
PressEnter;
printf("▼2\n▲函数 DestroySMatrix_OL 测试...\n"); //2.函数DestroySMatrix_OL测试
{
printf("销毁 M 前:");
!M.mu && !M.nu && !M.tu ? printf(" M 不存在!!\n") : printf(" M 存在!\n");
DestroySMatrix_OL(&M);
printf("销毁 M 后:");
!M.mu && !M.nu && !M.tu ? printf(" M 不存在!!\n") : printf(" M 存在!\n");
printf("\n");
}
PressEnter;
return 0;
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,78 @@
/********************************************
* *
* 文件夹: ▲05 数组和广义表\04 CrossList *
* *
* 文件名: CrossList.h *
* *
* 内 容: 十字链表(稀疏矩阵)相关操作列表 *
* *
********************************************/
#ifndef CROSSLIST_H
#define CROSSLIST_H
#include <stdio.h>
#include <stdlib.h> //提供malloc、realloc、free、exit原型
#include <stdarg.h> //提供宏va_list、va_start、va_arg、va_end
#include "../../▲01 绪论/Status.h" //**▲01 绪论**//
#include "../../▲01 绪论/Scanf.c" //**▲01 绪论**//
/* 十字链表类型定义 */
typedef int CElemType;
typedef struct OLNode
{
int i, j; //该非零元的行下标和列下标
CElemType e;
struct OLNode *right; //该非零元所在的行表的后继链域
struct OLNode *down; //该非零元所在的列表的后继链域
}OLNode;
typedef OLNode *OLink; //指向某一结点的指针
typedef struct
{
OLink *rhead; //行链表头指针
OLink *chead; //列链表头指针
int mu, nu, tu; //矩阵的行数、列数和非零元个数
}CrossList;
/* 十字链表(稀疏矩阵)函数列表 */
Status CreateSMatrix_OL(FILE *fp, int n, ...);
/*━━━━━━━━━━━━┓
┃(01)算法5.4创建矩阵M。┃
┗━━━━━━━━━━━━*/
void DestroySMatrix_OL(CrossList *M);
/*━━━━━━━┓
┃(02)销毁矩阵。┃
┗━━━━━━━*/
void PrintSMatrix_OL(CrossList M);
/*━━━━━━━┓
┃(03)输出矩阵。┃
┗━━━━━━━*/
void CopySMatrix_OL(CrossList M, CrossList *T);
/*━━━━━━━━┓
┃(04)矩阵的复制。┃
┗━━━━━━━━*/
Status AddSMatri_OL(CrossList M, CrossList N, CrossList *Q);
/*━━━━━━━━┓
┃(05)Q = M + N。 ┃
┗━━━━━━━━*/
Status SubSMatrix_OL(CrossList M, CrossList N, CrossList *Q);
/*━━━━━━━━┓
┃(06)Q = M - N。 ┃
┗━━━━━━━━*/
Status MultSMatrix_OL(CrossList M, CrossList N, CrossList *Q);
/*━━━━━━━━┓
┃(07)Q = M * N。 ┃
┗━━━━━━━━*/
void TransposeSMatrix_OL(CrossList M, CrossList *T);
/*━━━━━━━┓
┃(08)矩阵转置。┃
┗━━━━━━━*/
#endif

View File

@@ -0,0 +1,9 @@
行数5
列数5
非零元个数10
三元组:(1,2,1),(1,4,5),(2,3,-3),(2,5,2),(3,1,2),(3,2,3),(3,3,4),(4,4,2),(5,1,3),(5,2,-1)
行数5
列数5
非零元个数8
三元组:(1,1,-3)(1,3,2)(2,4,-1)(3,2,4)(4,1,6)(4,5,5)(5,1,3)(5,3,2)

View File

@@ -0,0 +1,157 @@
/****************************************************
* *
* 文件夹: ▲05 数组和广义表\05 GeneralizedList-H&T *
* *
* 内 容: 广义表(头尾链表存储)相关函数测试 *
* *
****************************************************/
#include <stdio.h>
#include "GeneralizedList-H-T.c" //**▲05 数组和广义表**//
void PrintElem(AtomType e); //打印广义表原子
int main(int argc, char **argv)
{
GList Tmp, G;
GList g1, g2, g3;
SString S1, S2, S3;
printf("▼1\n▲函数 InitGList_GL_H_T 测试...\n"); //1.函数InitGList_GL_H_T测试
{
printf("创建空的广义表 Tmp ...\n");
InitGList_GL_H_T(&Tmp);
printf("\n");
}
PressEnter;
printf("▼8\n▲函数 GListEmpty_GL_H_T 测试...\n"); //8.函数GListEmpty_GL_H_T测试
{
int tag;
tag = GListEmpty_GL_H_T(Tmp);
tag ? printf(" Tmp 为空!\n") : printf(" Tmp 不为空!!\n");
printf("\n");
}
PressEnter;
printf("▼2-1、3-1、2-2、3-2\n▲函数 sever_GL_H_T_1、CreateGList_GL_H_T_1等 测试...\n");
{ //2-1、3-1、2-2、3-2.函数sever_GL_H_T_1、CreateGList_GL_H_T_1等测试
char *s1 = "()";
char *s2 = "(e)";
char *s3 = "(a,(b,c,d))";
printf("创建广义表S1、S2、S3...\n");
StrAssign_Sq(S1, s1);
CreateGList_GL_H_T_1(&g1, S1);
StrAssign_Sq(S2, s2);
CreateGList_GL_H_T_1(&g2, S2);
StrAssign_Sq(S3, s3);
CreateGList_GL_H_T_2(&g3, S3);
printf("\n");
}
PressEnter;
printf("▼11\n▲函数 InsertFirst_GL_H_T 测试...\n"); //11.函数InsertFirst_GL_H_T测试
{
printf("将 S3、S2、S1 依次插入到 Tmp 的首个位置...\n");
InsertFirst_GL_H_T(&Tmp, g3);
InsertFirst_GL_H_T(&Tmp, g2);
InsertFirst_GL_H_T(&Tmp, g1);
printf("\n");
}
PressEnter;
printf("▼13\n▲函数 Traverse_GL_H_T 测试...\n"); //13.函数Traverse_GL_H_T测试
{
printf("输出广义表中原子 Tmp = ");
Traverse_GL_H_T(Tmp, PrintElem);
printf("\n\n");
}
PressEnter;
printf("▼14\n▲函数 Output_GL_H_T 测试...\n"); //14.函数Output_GL_H_T测试
{
printf("带括号输出广义表 Tmp = ");
Output_GL_H_T(Tmp, Head);
printf("\n\n");
}
PressEnter;
printf("▼5\n▲函数 CopyGList_GL_H_T 测试...\n"); //5.函数CopyGList_GL_H_T测试
{
printf("复制 Tmp 到 G = ");
CopyGList_GL_H_T(&G, Tmp);
Output_GL_H_T(G, Head);
printf("\n\n");
}
PressEnter;
printf("▼12\n▲函数 DeleteFirst_GL_H_T 测试...\n"); //12.函数DeleteFirst_GL_H_T测试
{
GList h;
printf("删除广义表 Tmp 的表头:");
DeleteFirst_GL_H_T(&Tmp, &h);
Output_GL_H_T(h, Head);
printf("\n");
printf(" Tmp = ");
Output_GL_H_T(Tmp, Head);
printf("\n\n");
}
PressEnter;
printf("▼6\n▲函数 GListLength_GL_H_T 测试...\n"); //6.函数GListLength_GL_H_T测试
{
printf("广义表 G 的长度为: %d \n", GListLength_GL_H_T(G));
printf("\n");
}
PressEnter;
printf("▼7\n▲函数 GListDepth_GL_H_T 测试...\n"); //7.函数GListDepth_GL_H_T测试
{
printf("广义表 G 的深度为: %d\n", GListDepth_GL_H_T(G));
printf("\n");
}
PressEnter;
printf("▼9\n▲函数 GetHead_GL_H_T 测试...\n"); //9.函数GetHead_GL_H_T测试
{
GList H;
printf("广义表 G 的表头 H = ");
H = GetHead_GL_H_T(G);
Output_GL_H_T(H, Head);
printf("\n\n");
}
PressEnter;
printf("▼10\n▲函数 GetTail_GL_H_T 测试...\n"); //10.函数GetTail_GL_H_T测试
{
GList T;
printf("广义表 G 的表尾 T = ");
T = GetTail_GL_H_T(G);
Output_GL_H_T(T, Head);
printf("\n\n");
}
PressEnter;
printf("▼4\n▲函数 ClearGList_GL_H_T 测试...\n"); //4.函数ClearGList_GL_H_T测试
{
printf("销毁 G 前:");
G ? printf(" G 存在!\n") : printf(" G 不存在!!\n");
ClearGList_GL_H_T(&G);
printf("销毁 G 后:");
G ? printf(" G 存在!\n") : printf(" G 不存在!!\n");
printf("\n");
}
PressEnter;
return 0;
}
void PrintElem(AtomType e)
{
printf("%d ", e);
}

View File

@@ -0,0 +1,379 @@
/****************************************************
* *
* 文件夹: ▲05 数组和广义表\05 GeneralizedList-H&T *
* *
* 文件名: GeneralizedList-H-T.c *
* *
* 算 法: 5.5、5.6、5.7、5.8 *
* *
****************************************************/
#ifndef GENERALIZEDLIST_H_T_C
#define GENERALIZEDLIST_H_T_C
#include "GeneralizedList-H-T.h" //**▲05 数组和广义表**//
void InitGList_GL_H_T(GList *L)
{
*L = NULL; //初始化了一个空表长度为0深度为1
}
/*════╗
║ 算法5.8║
╚════*/
/* 假设广义表各字符间无空格,且输入正确 */
void sever_GL_H_T_1(SString hstr, SString str) //str最外层已无括号
{
int i, k, n;
SString ch;
n = StrLength_Sq(str);
i = k = 0;
do
{
++i;
SubString_Sq(ch, str, i, 1);
if(ch[1]=='(')
++k;
if(ch[1]==')')
--k;
}while(i<n && (ch[1]!=',' || k!=0));
if(i<n)
{
SubString_Sq(hstr, str, 1, i-1);
SubString_Sq(str, str, i+1, n-i);
}
else
{
StrCopy_Sq(hstr, str);
ClearString_Sq(str);
}
}
/*════╗
║ 算法5.7║
╚════*/
void CreateGList_GL_H_T_1(GList *L, SString S)
{
SString emp, hsub, sub;
GList p, q;
StrAssign_Sq(emp, "()");
if(!StrCompare_Sq(S, emp)) //S代表空表
*L = NULL; //创建空表
else
{
*L = (GList)malloc(sizeof(GLNode));
if(!*L)
exit(OVERFLOW);
if(StrLength_Sq(S)==1) //创建单原子广义表
{
(*L)->tag = Atom;
(*L)->Union.atom = S[1];
(*L)->mark = 0; //GarbageCollection.c
}
else
{
(*L)->tag = List;
(*L)->mark = 0; //GarbageCollection.c
p = *L;
SubString_Sq(sub, S, 2, StrLength_Sq(S)-2); //去掉最外层括号
do //重复建n个子表
{
sever_GL_H_T_1(hsub, sub); //分离出表头串hsub
CreateGList_GL_H_T_1(&(p->Union.ptr.hp), hsub);
q = p;
if(!StrEmpty_Sq(sub)) //表尾不为空,处理表尾
{
p = (GList)malloc(sizeof(GLNode));
if(!p)
exit(OVERFLOW);
p->tag = List;
p->mark = 0; //GarbageCollection.c
q->Union.ptr.tp = p;
}
}while(!StrEmpty_Sq(sub));
q->Union.ptr.tp = NULL;
}
}
}
/* 另一种创建广义表的算法,与上述算法略有不同 */
/* 假设广义表各字符间无空格,且输入正确 */
void sever_GL_H_T_2(SString hstr, SString str) //将str分解为表头元素和表尾元素两部分
{
int i = 1;
int k = 0;
int n;
SString tmp;
SubString_Sq(tmp, str, 2, StrLength_Sq(str)-2);
n = StrLength_Sq(tmp);
while(i<n && (tmp[i]!=',' || k!=0))
{
if(tmp[i]=='(')
k++;
if(tmp[i]==')')
k--;
i++;
}
if(i<n)
SubString_Sq(hstr, tmp, 1, i-1);
else
StrCopy_Sq(hstr, tmp);
StrDelete_Sq(str, 2, i);
}
void CreateGList_GL_H_T_2(GList *L, SString S)
{
SString hsub, sub, emp;
GList p, q;
StrAssign_Sq(emp, "()");
if(!StrCompare_Sq(S, emp))
*L = NULL;
else
{
*L = (GList)malloc(sizeof(GLNode));
if(StrLength_Sq(S)==1)
{
(*L)->tag = Atom;
(*L)->Union.atom = S[1];
}
else
{
(*L)->tag = List;
p = *L;
StrCopy_Sq(sub, S);
do
{
sever_GL_H_T_2(hsub, sub);
CreateGList_GL_H_T_2(&(p->Union.ptr.hp), hsub);
if(StrCompare_Sq(sub, emp))
{
q = p;
p = (GList)malloc(sizeof(GLNode));
p->tag = List;
q->Union.ptr.tp = p;
}
}while(StrCompare_Sq(sub, emp));
p->Union.ptr.tp = NULL;
}
}
}
void ClearGList_GL_H_T(GList *L)
{
GList p, q;
if(*L)
{
if((*L)->tag==Atom)
{
free(*L); //删除原子结点
*L = NULL;
}
else //删除表结点
{
p = (*L)->Union.ptr.hp;
q = (*L)->Union.ptr.tp;
free(*L);
*L = NULL;
ClearGList_GL_H_T(&p);
ClearGList_GL_H_T(&q);
}
}
}
/*════╗
║ 算法5.6║
╚════*/
void CopyGList_GL_H_T(GList *T, GList L)
{
if(!L)
*T = NULL;
else
{
*T = (GList)malloc(sizeof(GLNode)); //建表结点
if(!*T)
exit(OVERFLOW);
(*T)->tag = L->tag;
if(L->tag==Atom) //复制单原子
(*T)->Union.atom = L->Union.atom;
else //复制表头和表尾
{
CopyGList_GL_H_T(&((*T)->Union.ptr.hp), L->Union.ptr.hp);
CopyGList_GL_H_T(&((*T)->Union.ptr.tp), L->Union.ptr.tp);
}
}
}
int GListLength_GL_H_T(GList L)
{
int count;
for(count=0; L; count++,L=L->Union.ptr.tp)
;
return count;
}
/*════╗
║ 算法5.5║
╚════*/
int GListDepth_GL_H_T(GList L)
{
int max, deep;
GList p;
if(!L) //空表深度为1
return 1;
if(L->tag==Atom) //原子深度为0
return 0;
for(max=0,p=L; p; p=p->Union.ptr.tp)
{
deep = GListDepth_GL_H_T(p->Union.ptr.hp);
if(deep>max)
max = deep;
}
return max + 1; //非空表的深度是各元素最大深度加一
}
Status GListEmpty_GL_H_T(GList L)
{
if(!L)
return TRUE;
else
return FALSE;
}
GList GetHead_GL_H_T(GList L)
{
GList p;
if(!L)
{
printf("广义表为空表,无法获取表头!\n");
exit(ERROR);
}
CopyGList_GL_H_T(&p, L->Union.ptr.hp);
return p;
}
GList GetTail_GL_H_T(GList L)
{
GList p;
if(!L)
{
printf("广义表为空表,无法获取表尾!\n");
exit(ERROR);
}
CopyGList_GL_H_T(&p, L->Union.ptr.tp);
return p;
}
void InsertFirst_GL_H_T(GList *L, GList e)
{
GList g;
g = (GList)malloc(sizeof(GLNode));
if(!g)
exit(OVERFLOW);
g->tag = 1;
g->Union.ptr.hp = e;
g->Union.ptr.tp = *L;
*L = g;
}
void DeleteFirst_GL_H_T(GList *L, GList *e)
{
GList p;
if(!(*L))
{
printf("广义表为空表,删除表头失败!\n");
exit(ERROR);
}
p = *L;
*L = (*L)->Union.ptr.tp;
CopyGList_GL_H_T(e, p->Union.ptr.hp);
free(p);
p = NULL;
}
void Traverse_GL_H_T(GList L, void(Visit)(AtomType))
{
if(L)
{
if(L->tag==Atom)
Visit(L->Union.atom);
else
{
Traverse_GL_H_T(L->Union.ptr.hp, Visit);
Traverse_GL_H_T(L->Union.ptr.tp, Visit);
}
}
}
void Output_GL_H_T(GList L, Mark mark)
{
if(!L) //L为空
{
if(mark==Head) //mark=0代表广义表指针来自表头
printf("()");
else //mark=1代表广义表指针来自表尾
printf(")");
}
else //L不为空时
{
if(L->tag==Atom) //对于原子结点,输出原子
printf("%c",L->Union.atom);
else //对于表结点,要对表头、表尾分别讨论
{
if(mark==Head)
printf("(");
else
printf(",");
Output_GL_H_T(L->Union.ptr.hp, Head);
Output_GL_H_T(L->Union.ptr.tp, Tail);
}
}
}
#endif

View File

@@ -0,0 +1,122 @@
/****************************************************
* *
* 文件夹: ▲05 数组和广义表\05 GeneralizedList-H&T *
* *
* 文件名: GeneralizedList-H-T.h *
* *
* 内 容: 广义表(头尾链表存储表示)相关操作列表 *
* *
****************************************************/
#ifndef GENERALIZEDLIST_H_T_H
#define GENERALIZEDLIST_H_T_H
#include <stdio.h>
#include <stdlib.h> //提供malloc、realloc、free、exit原型
#include "../../▲01 绪论/Status.h" //**▲01 绪论**//
#include "../../▲04 串/01 SequenceString/SequenceString.c" //**▲04 串**//
/* 广义表(头尾链表存储表示)类型定义 */
typedef enum{ Head, Tail }Mark;
typedef enum{ Atom, List }ElemTag; //Atom==0原子结点List==1表结点
typedef char AtomType; //原子类型
typedef struct GLNode
{
union{ int mark; }; //匿名联合仅在第8章广义表遍历算法中使用
ElemTag tag; //公共部分,用于区分原子结点和表结点
union //原子结点和表结点的联合部分
{
AtomType atom; //atom是原子结点的值域AtomType由用户定义
struct
{
struct GLNode *hp; //指向表头
struct GLNode *tp; //指向表尾
}ptr; //表结点的指针域
}Union;
}GLNode;
typedef GLNode* GList; //广义表类型
/* 广义表(头尾链表存储)函数列表 */
/* ★每一层去掉括号考察★ */
void InitGList_GL_H_T(GList *L);
/*━━━━━━━━━━━━━━━━━━━┓
┃(01)初始化广义链表(创建空的广义表)。┃
┗━━━━━━━━━━━━━━━━━━━*/
void sever_GL_H_T_1(SString hstr, SString str);
/*━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
┃(02-1)算法5.8将非空串str分割成两部分:hsub为第一个','之前的子串,str为之后的子串。┃
┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━*/
void CreateGList_GL_H_T_1(GList *L, SString S);
/*━━━━━━━━━━━━━━━┓
┃(03-1)算法5.7由S创建广义表。┃
┗━━━━━━━━━━━━━━━*/
void sever_GL_H_T_2(SString hstr, SString str);
/*━━━━━━━━━━━━━━━━━━━━━━━━━━┓
┃(02-2)将非空串str分割成两部分:hsub做表头,str做表尾。┃
┗━━━━━━━━━━━━━━━━━━━━━━━━━━*/
void CreateGList_GL_H_T_2(GList *L, SString S);
/*━━━━━━━━━━━┓
┃(03-2)由S创建广义表。 ┃
┗━━━━━━━━━━━*/
void ClearGList_GL_H_T(GList *L);
/*━━━━━━━━━━━━━━┓
┃(04)清空广义表(无法销毁)。┃
┗━━━━━━━━━━━━━━*/
void CopyGList_GL_H_T(GList *T, GList L);
/*━━━━━━━━━━━━━┓
┃(05)算法5.6:复制广义表。 ┃
┗━━━━━━━━━━━━━*/
int GListLength_GL_H_T(GList L);
/*━━━━━━━━━┓
┃(06)求广义表长度。┃
┗━━━━━━━━━*/
int GListDepth_GL_H_T(GList L);
/*━━━━━━━━━━━━━━┓
┃(07)算法5.5:求广义表深度。 ┃
┗━━━━━━━━━━━━━━*/
Status GListEmpty_GL_H_T(GList L);
/*━━━━━━━━━━━━┓
┃(08)判断广义表是否为空。┃
┗━━━━━━━━━━━━*/
GList GetHead_GL_H_T(GList L);
/*━━━━━━━┓
┃(09)获取表头。┃
┗━━━━━━━*/
GList GetTail_GL_H_T(GList L);
/*━━━━━━━┓
┃(10)获取表尾。┃
┗━━━━━━━*/
void InsertFirst_GL_H_T(GList *L, GList e);
/*━━━━━━━━━━━━━━━┓
┃(11)插入e为广义表第一个元素。 ┃
┗━━━━━━━━━━━━━━━*/
void DeleteFirst_GL_H_T(GList *L, GList *e);
/*━━━━━━━━━━━━━━━┓
┃(12)删除广义表表头并用e返回。 ┃
┗━━━━━━━━━━━━━━━*/
void Traverse_GL_H_T(GList L, void(Visit)(AtomType));
/*━━━━━━━━┓
┃(13)遍历广义表。┃
┗━━━━━━━━*/
void Output_GL_H_T(GList L, Mark mark);
/*━━━━━━━━━━━━━━━━━━┓
┃(14)带括号输出广义表Lmark为标记。 ┃
┗━━━━━━━━━━━━━━━━━━*/
#endif

View File

@@ -0,0 +1,158 @@
/**************************************************
* *
* 文件夹: ▲05 数组和广义表\06 GeneralizedList-E *
* *
* 内 容: 广义表(扩展线性链表存储)相关函数测试 *
* *
*************************************************/
#include <stdio.h>
#include "GeneralizedList-E.c" //**▲05 数组和广义表**//
void PrintElem(AtomType e); //打印广义表原子
int main(int argc, char **argv)
{
GList Tmp, G;
GList g1, g2, g3;
SString S1, S2, S3;
printf("▼1\n▲函数 InitGList_GL_E 测试...\n"); //1.函数InitGList_GL_E测试
{
printf("创建空的广义表 Tmp ...\n");
InitGList_GL_E(&Tmp);
printf("\n");
}
PressEnter;
printf("▼8\n▲函数 GListEmpty_GL_E 测试...\n"); //8.函数GListEmpty_GL_E测试
{
int tag;
tag = GListEmpty_GL_E(Tmp);
tag ? printf(" Tmp 为空!\n") : printf(" Tmp 不为空!!\n");
printf("\n");
}
PressEnter;
printf("▼2、3\n▲函数 sever_GL_E、CreateGList_GL_E 测试...\n"); //2、3.函数sever_GL_E、CreateGList_GL_E测试
{
char *s1 = "()";
char *s2 = "(e)";
char *s3 = "(a,(b,c,d))";
printf("创建广义表S1、S2、S3...\n");
StrAssign_Sq(S1, s1);
CreateGList_GL_E(&g1, S1);
StrAssign_Sq(S2, s2);
CreateGList_GL_E(&g2, S2);
StrAssign_Sq(S3, s3);
CreateGList_GL_E(&g3, S3);
printf("\n");
}
PressEnter;
printf("▼11\n▲函数 InsertFirst_GL_E 测试...\n"); //11.函数InsertFirst_GL_H_T测试
{
printf("将 S3、S2、S1 依次插入到 Tmp 的首个位置...\n");
InsertFirst_GL_E(&Tmp, g3);
InsertFirst_GL_E(&Tmp, g2);
InsertFirst_GL_E(&Tmp, g1);
printf("\n");
}
PressEnter;
printf("▼13\n▲函数 Traverse_GL_E 测试...\n"); //13.函数Traverse_GL_E测试
{
printf("输出广义表中原子 Tmp = ");
Traverse_GL_E(Tmp, PrintElem);
printf("\n\n");
}
PressEnter;
printf("▼14\n▲函数 Output_GL_E 测试...\n"); //14.函数Output_GL_E测试
{
printf("带括号输出广义表 Tmp = ");
Output_GL_E(Tmp);
printf("\n\n");
}
PressEnter;
printf("▼5\n▲函数 CopyGList_GL_E 测试...\n"); //5.函数CopyGList_GL_E测试
{
printf("复制 Tmp 到 G = ");
CopyGList_GL_E(&G, Tmp);
Output_GL_E(G);
printf("\n\n");
}
PressEnter;
printf("▼12\n▲函数 DeleteFirst_GL_E 测试...\n"); //12.函数DeleteFirst_GL_E测试
{
GList h;
printf("删除广义表 Tmp 的表头:");
DeleteFirst_GL_E(&Tmp, &h);
Output_GL_E(h);
printf("\n");
printf(" Tmp = ");
Output_GL_E(Tmp);
printf("\n\n");
}
PressEnter;
printf("▼6\n▲函数 GListLength_GL_E 测试...\n"); //6.函数GListLength_GL_E测试
{
printf("广义表 G 的长度为:%d\n", GListLength_GL_E(G));
printf("\n");
}
PressEnter;
printf("▼7-1、7-2\n▲函数 GListDepth_GL_E_1等 测试...\n"); //7-1、7-2.函数GListDepth_GL_E_1等测试
{
printf("广义表 Tmp 的深度为:%d\n", GListDepth_GL_E_1(Tmp));
printf("广义表 G 的深度为:%d\n", GListDepth_GL_E_2(G));
printf("\n");
}
PressEnter;
printf("▼9\n▲函数 GetHead_GL_E 测试...\n"); //9.函数GetHead_GL_E测试
{
GList H;
printf("获取广义表 G 的表头 H = ");
H = GetHead_GL_E(G);
Output_GL_E(H);
printf("\n\n");
}
PressEnter;
printf("▼10\n▲函数 GetTail_GL_E 测试...\n"); //10.函数GetTail_GL_E测试
{
GList T;
printf("获取广义表 G 的表尾 T = ");
T = GetTail_GL_E(G);
Output_GL_E(T);
printf("\n\n");
}
PressEnter;
printf("▼4\n▲函数 DestroyGList_GL_E 测试...\n"); //4.函数DestroyGList_GL_E测试
{
printf("销毁 G 前:");
G ? printf(" G 存在!\n") : printf(" G 不存在!!\n");
DestroyGList_GL_E(&G);
printf("销毁 G 后:");
G ? printf(" G 存在!\n") : printf(" G 不存在!!\n");
printf("\n");
}
PressEnter;
return 0;
}
void PrintElem(AtomType e)
{
printf("%d ", e);
}

View File

@@ -0,0 +1,403 @@
/**************************************************
* *
* 文件夹: ▲05 数组和广义表\06 GeneralizedList-E *
* *
* 文件名: GeneralizedList-E.c *
* *
*************************************************/
#ifndef GENERALIZEDLIST_E_C
#define GENERALIZEDLIST_E_C
#include "GeneralizedList-E.h" //**▲05 数组和广义表**//
void InitGList_GL_E(GList *L)
{
*L = (GList)malloc(sizeof(GLNode));
if(!*L)
exit(OVERFLOW);
(*L)->tag = List;
(*L)->Union.hp = NULL;
(*L)->tp = NULL;
}
void sever_GL_E(SString hstr, SString str)
{
int i, k, n;
SString ch;
n = StrLength_Sq(str);
i = k = 0;
do
{
++i;
SubString_Sq(ch, str, i, 1);
if(ch[1]=='(')
++k;
if(ch[1]==')')
--k;
}while(i<n && (ch[1]!=',' || k!=0));
if(i<n)
{
SubString_Sq(hstr, str, 1, i-1);
SubString_Sq(str, str, i+1, n-i);
}
else
{
StrCopy_Sq(hstr, str);
ClearString_Sq(str);
}
}
void CreateGList_GL_E(GList *L, SString S)
{
SString emp, hsub, sub, tmp;
GList p, q;
StrAssign_Sq(emp, "()");
StrCopy_Sq(sub, S); //复制是为了不破坏S
sever_GL_E(hsub, sub);
*L = (GList) malloc (sizeof(GLNode));
if(!*L)
exit(OVERFLOW);
if(!StrCompare_Sq(hsub, emp))
{
(*L)->tag = List;
(*L)->Union.hp = NULL;
}
else
{
if(StrLength_Sq(hsub)==1)
{
(*L)->tag = Atom;
(*L)->Union.atom = hsub[1];
}
else
{
(*L)->tag = List;
SubString_Sq(tmp, hsub, 2, StrLength_Sq(hsub)-2);
CreateGList_GL_E(&((*L)->Union.hp), tmp);
}
}
if(StrEmpty_Sq(sub))
(*L)->tp = NULL;
else
CreateGList_GL_E(&((*L)->tp), sub);
}
void DestroyGList_GL_E(GList *L)
{
GList p, q;
if(*L)
{
if((*L)->tag==List) //处理表结点
{
p = (*L)->Union.hp;
q = (*L)->tp;
free(*L);
*L = NULL;
if(p)
DestroyGList_GL_E(&p); //递归处理表头
if(q)
DestroyGList_GL_E(&q); //递归处理表尾
}
else //处理原子结点
{
q = (*L)->tp;
free(*L);
*L = NULL;
if(q)
DestroyGList_GL_E(&q);
}
}
}
void CopyGList_GL_E(GList *T, GList L)
{
if(L)
{
*T = (GList) malloc (sizeof(GLNode));
if(!*T)
exit(OVERFLOW);
if(L->tag==Atom)
{
(*T)->tag = Atom;
(*T)->Union.atom = L->Union.atom;
}
else
{
(*T)->tag = List;
if(L->Union.hp)
CopyGList_GL_E(&((*T)->Union.hp), L->Union.hp);
else
(*T)->Union.hp = NULL;
}
if(L->tp)
CopyGList_GL_E(&((*T)->tp), L->tp);
else
(*T)->tp = NULL;
}
else
{
printf("广义表不存在!!\n");
exit(OVERFLOW);
}
}
int GListLength_GL_E(GList L)
{
int i = 0;
GList p;
if(!L)
{
printf("广义表不存在!!\n");
exit(OVERFLOW);
}
p = L->Union.hp;
while(p)
{
++i;
p = p->tp;
}
return i;
}
int GListDepth_GL_E_1(GList L)
{
int max, deep;
GList p;
max = 0;
if(!L)
{
printf("广义表不存在!!\n");
exit(OVERFLOW);
}
if(L->tag==List && !L->Union.hp) //空表深度为1
return 1;
else if(L->tag==Atom) //单原子表深度为0只会出现在递归调用中
return 0;
else //求一般表的深度
{
for(p=L->Union.hp; p; p=p->tp)
{
deep = GListDepth_GL_E_1(p); //求以p为头指针的子表深度
if(deep>max)
max = deep;
}
}
return max + 1;
}
// 对于表结点,分横向深度和纵向深度讨论。跳过原子结点
int GListDepth_GL_E_2(GList L)
{
int max, deep;
GList p = L;
max = deep = 0;
if(!L)
{
printf("广义表L不存在\n");
exit(OVERFLOW);
}
else
{
if(L->tag==List) //处理表结点
{
max++; //一个表结点代表一个深度
if(L->Union.hp)
{
deep = GListDepth_GL_E_2(L->Union.hp);
max += deep; //纵向深度不断累加
}
do //跳过同一层原子结点
{
p = p->tp;
}while(p && p->tag!=List);
}
else //处理原子结点
{
while(p && p->tag!=List) //跳过同一层原子结点
p = p->tp;
}
if(p)
{
deep = GListDepth_GL_E_2(p);
if(deep>max) //max保存同一层各结点的最大深度
max = deep; //横向深度取最大的一个
}
}
return max;
}
Status GListEmpty_GL_E(GList L)
{
if(!L)
{
printf("广义表不存在!!\n");
exit(OVERFLOW);
}
if(L->tag==List && !(L->Union.hp) && !(L->tp))
return TRUE;
else
return ERROR;
}
GList GetHead_GL_E(GList L)
{
GList p, q;
if(!L)
{
printf("广义表不存在!!\n");
exit(OVERFLOW);
}
if(!L->Union.hp)
{
printf("广义表为空表,无法获取表头!\n");
exit(OVERFLOW);
}
q = L->Union.hp->tp; //q保存L的表尾
L->Union.hp->tp = NULL; //截去L的表尾部分
CopyGList_GL_E(&p, L->Union.hp); //将表头元素复制给h
L->Union.hp->tp = q; //恢复L的表尾
return p;
}
GList GetTail_GL_E(GList L)
{
GList p, q;
if(!L)
{
printf("广义表不存在!!\n");
exit(OVERFLOW);
}
if(!L->Union.hp)
{
printf("广义表为空表,无法获取表尾!\n");
exit(OVERFLOW);
}
InitGList_GL_E(&p);
q = L->Union.hp;
do
{
q = q->tp;
}while(q && q->tp);
p->Union.hp = q;
return p;
}
void InsertFirst_GL_E(GList *L, GList e)
{
GList g;
if(!*L)
{
printf("广义表不存在!!\n");
exit(OVERFLOW);
}
CopyGList_GL_E(&g, e);
g->tp = (*L)->Union.hp;
(*L)->Union.hp = g;
}
void DeleteFirst_GL_E(GList *L, GList *e)
{
GList p;
if(!*L)
{
printf("广义表不存在!!\n");
exit(OVERFLOW);
}
if(!(*L)->Union.hp)
{
printf("广义表为空表,删除表头失败!\n");
exit(OVERFLOW);
}
p = (*L)->Union.hp;
(*L)->Union.hp = p->tp;
p->tp = NULL;
*e = p;
}
void Traverse_GL_E(GList L, void(Visit)(AtomType))
{
if(L)
{
if(L->tag==List)
Traverse_GL_E(L->Union.hp, Visit);
else
Visit(L->Union.atom);
Traverse_GL_E(L->tp, Visit);
}
}
void Output_GL_E(GList L)
{
if(L)
{
if(L->tag==List) //处理表结点
{
printf("(");
if(L->Union.hp)
Output_GL_E(L->Union.hp);
if(L->tp)
{
printf("),");
Output_GL_E(L->tp);
}
else
printf(")");
}
else //处理原子结点
{
printf("%c",L->Union.atom);
if(L->tp)
{
printf(",");
Output_GL_E(L->tp);
}
}
}
}
#endif

View File

@@ -0,0 +1,111 @@
/******************************************************
* *
* 文件夹: ▲05 数组和广义表\06 GeneralizedList-E *
* *
* 文件名: GeneralizedList-E.h *
* *
* 内 容: 广义表(扩展线性链表存储表示)相关操作列表 *
* *
******************************************************/
#ifndef GENERALIZEDLIST_E_H
#define GENERALIZEDLIST_E_H
#include <stdio.h>
#include <stdlib.h> //提供malloc、realloc、free、exit原型
#include "../../▲01 绪论/Status.h" //**▲01 绪论**//
#include "../../▲04 串/01 SequenceString/SequenceString.c" //**▲04 串**//
/* 广义表(扩展线性链表存储表示)类型定义 */
typedef enum { Atom, List }ElemTag; //Atom==0原子结点List==1表结点
typedef char AtomType; //原子类型
typedef struct GLNode
{
ElemTag tag; //公共部分,用于区分原子结点和表结点
union //原子结点和表结点的联合部分
{
AtomType atom; //原子结点值域
struct GLNode *hp; //表结点的表头指针
}Union;
struct GLNode *tp; //相当于线性链表的next指向下一个元素结点
}GLNode;
typedef GLNode* GList; //广义表类型
/* 广义表(扩展线性链表存储)基础操作 */
/* ★每一层带上括号考察★ */
void InitGList_GL_E(GList *L);
/*━━━━━━━━━━━━━━━━━━━┓
┃(01)初始化广义链表(创建空的广义表)。┃
┗━━━━━━━━━━━━━━━━━━━*/
void sever_GL_E(SString hstr, SString str);
/*━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
┃(02)将非空串str分割成两部分:hstr为第一个','之前的子串,str为之后的子串。 ┃
┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━*/
void CreateGList_GL_E(GList *L, SString S);
/*━━━━━━━━━━┓
┃(03)由S创建广义表。 ┃
┗━━━━━━━━━━*/
void DestroyGList_GL_E(GList *L);
/*━━━━━━━━┓
┃(04)销毁广义表。┃
┗━━━━━━━━*/
void CopyGList_GL_E(GList *T, GList L);
/*━━━━━━━━┓
┃(05)复制广义表。┃
┗━━━━━━━━*/
int GListLength_GL_E(GList L);
/*━━━━━━━━━┓
┃(06)求广义表长度。┃
┗━━━━━━━━━*/
int GListDepth_GL_E_1(GList L);
/*━━━━━━━━━━┓
┃(07-1)求广义表深度。┃
┗━━━━━━━━━━*/
int GListDepth_GL_E_2(GList L);
/*━━━━━━━━━━┓
┃(07-2)求广义表深度。┃
┗━━━━━━━━━━*/
Status GListEmpty_GL_E(GList L);
/*━━━━━━━━━━━━┓
┃(08)判断广义表是否为空。┃
┗━━━━━━━━━━━━*/
GList GetHead_GL_E(GList L);
/*━━━━━━━┓
┃(09)获取表头。┃
┗━━━━━━━*/
GList GetTail_GL_E(GList L);
/*━━━━━━━┓
┃(10)获取表尾。┃
┗━━━━━━━*/
void InsertFirst_GL_E(GList *L, GList e);
/*━━━━━━━━━━━━━━━┓
┃(11)插入e作为广义表第一元素。 ┃
┗━━━━━━━━━━━━━━━*/
void DeleteFirst_GL_E(GList *L, GList *e);
/*━━━━━━━━━━━━━━━━━┓
┃(12)删除广义表第一元素并用e返回。 ┃
┗━━━━━━━━━━━━━━━━━*/
void Traverse_GL_E(GList L, void(Visit)(AtomType));
/*━━━━━━━━┓
┃(13)遍历广义表。┃
┗━━━━━━━━*/
void Output_GL_E(GList L);
/*━━━━━━━━━━━━┓
┃(14)带括号输出广义表L。 ┃
┗━━━━━━━━━━━━*/
#endif