mirror of
https://github.com/kangjianwei/Data-Structure.git
synced 2026-02-07 00:42:17 +08:00
💡 【教材】 ▲05 数组和广义表
This commit is contained in:
73
▲课本算法实现/▲05 数组和广义表/01 SequenceArray/SequenceArray-main.c
Normal file
73
▲课本算法实现/▲05 数组和广义表/01 SequenceArray/SequenceArray-main.c
Normal 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;
|
||||
}
|
||||
142
▲课本算法实现/▲05 数组和广义表/01 SequenceArray/SequenceArray.c
Normal file
142
▲课本算法实现/▲05 数组和广义表/01 SequenceArray/SequenceArray.c
Normal 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
|
||||
63
▲课本算法实现/▲05 数组和广义表/01 SequenceArray/SequenceArray.h
Normal file
63
▲课本算法实现/▲05 数组和广义表/01 SequenceArray/SequenceArray.h
Normal 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
|
||||
@@ -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)
|
||||
@@ -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;
|
||||
}
|
||||
372
▲课本算法实现/▲05 数组和广义表/02 TripleSparseMatrix/TripleSparseMatrix.c
Normal file
372
▲课本算法实现/▲05 数组和广义表/02 TripleSparseMatrix/TripleSparseMatrix.c
Normal 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
|
||||
@@ -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
|
||||
@@ -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;
|
||||
}
|
||||
504
▲课本算法实现/▲05 数组和广义表/03 RowLinkSparseMatrix/RowLinkSparseMatrix.c
Normal file
504
▲课本算法实现/▲05 数组和广义表/03 RowLinkSparseMatrix/RowLinkSparseMatrix.c
Normal file
File diff suppressed because it is too large
Load Diff
@@ -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.3:Q = M * N。┃
|
||||
┗━━━━━━━━━━━━*/
|
||||
|
||||
void TransposeSMatrix_RL(RLSMatrix M, RLSMatrix *T);
|
||||
/*━━━━━━━┓
|
||||
┃(08)矩阵转置。┃
|
||||
┗━━━━━━━*/
|
||||
|
||||
void FastTransposeSMatrix_RL(RLSMatrix M, RLSMatrix *T);
|
||||
/*━━━━━━━━━┓
|
||||
┃(09)矩阵快速转置。┃
|
||||
┗━━━━━━━━━*/
|
||||
|
||||
#endif
|
||||
@@ -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)
|
||||
105
▲课本算法实现/▲05 数组和广义表/04 CrossList/CrossList-main.c
Normal file
105
▲课本算法实现/▲05 数组和广义表/04 CrossList/CrossList-main.c
Normal 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;
|
||||
}
|
||||
694
▲课本算法实现/▲05 数组和广义表/04 CrossList/CrossList.c
Normal file
694
▲课本算法实现/▲05 数组和广义表/04 CrossList/CrossList.c
Normal file
File diff suppressed because it is too large
Load Diff
78
▲课本算法实现/▲05 数组和广义表/04 CrossList/CrossList.h
Normal file
78
▲课本算法实现/▲05 数组和广义表/04 CrossList/CrossList.h
Normal 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
|
||||
9
▲课本算法实现/▲05 数组和广义表/04 CrossList/TestData_CrossList.txt
Normal file
9
▲课本算法实现/▲05 数组和广义表/04 CrossList/TestData_CrossList.txt
Normal 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)
|
||||
@@ -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);
|
||||
}
|
||||
379
▲课本算法实现/▲05 数组和广义表/05 GeneralizedList-H&T/GeneralizedList-H-T.c
Normal file
379
▲课本算法实现/▲05 数组和广义表/05 GeneralizedList-H&T/GeneralizedList-H-T.c
Normal 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
|
||||
122
▲课本算法实现/▲05 数组和广义表/05 GeneralizedList-H&T/GeneralizedList-H-T.h
Normal file
122
▲课本算法实现/▲05 数组和广义表/05 GeneralizedList-H&T/GeneralizedList-H-T.h
Normal 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)带括号输出广义表L,mark为标记。 ┃
|
||||
┗━━━━━━━━━━━━━━━━━━*/
|
||||
|
||||
#endif
|
||||
158
▲课本算法实现/▲05 数组和广义表/06 GeneralizedList-E/GeneralizedList-E-main.c
Normal file
158
▲课本算法实现/▲05 数组和广义表/06 GeneralizedList-E/GeneralizedList-E-main.c
Normal 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);
|
||||
}
|
||||
403
▲课本算法实现/▲05 数组和广义表/06 GeneralizedList-E/GeneralizedList-E.c
Normal file
403
▲课本算法实现/▲05 数组和广义表/06 GeneralizedList-E/GeneralizedList-E.c
Normal 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
|
||||
111
▲课本算法实现/▲05 数组和广义表/06 GeneralizedList-E/GeneralizedList-E.h
Normal file
111
▲课本算法实现/▲05 数组和广义表/06 GeneralizedList-E/GeneralizedList-E.h
Normal 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
|
||||
Reference in New Issue
Block a user