数组和广义表
矩阵的快速转置
#include <stdio.h>
#include <stdlib.h>
#define MAXSIZE 30
typedef struct
{
int i;//行号
int j;//列号
int v;//非零元素之
}TNode;//三元组类型
typedef struct
{
int m;//矩阵行数
int n;//矩阵列数
int t;//矩阵中非零元素个数
TNode data[MAXSIZE];//三元组表
}TSMatrix;//三元组表类型
void CreatMat(TSMatrix *p,inta[3][4],int m,int n)//建立三元组表
{
int i,j;
p->m=m;
p->n=n;
p->t=0;//p->t指向三元组表的第一个三元组位置
for(i=0;i<m;i++)
{
for(j=0;j<n;j++)
if(a[i][j]!=0)//将非零元素存储于三元组表data中
{
p->data[p->t].i=i;
p->data[p->t].j=j;
p->data[p->t].v=a[i][j];
p->t++;//下标加1以便三元组表a存放下一个非零元素
}
}
}
void FastTranTat(TSMatrix*a,TSMatrix *b)//矩阵快速转置
{
int i,k,pot[MAXSIZE];
b->m=a->m;
b->n=a->n;
b->t=a->t;
if(b->t!=0)//当三元组表不为空时
{
for(k=1;k<a->n;k++)
pot[k]=0;//pot数组初始化
for(i=0;i<a->t;i++)
{
k=a->data[i].j;
pot[k+1]=pot[k+1]+1;//统计第k列非零元素的个数并送入pot[k+1]
}
pot[0]=0;//第0列第一个非零元素在表b中的位置
for(k=1;k<a->n;k++)
pot[k]=pot[k-1]+pot[k];//第1··第n-1列第一个非零元素在表b中的存放位置
for(i=0;i<a->t;i++)
{
k=a->data[i].j;
b->data[pot[k]].i=a->data[i].j;
b->data[pot[k]].j=a->data[i].i;
b->data[pot[k]].v=a->data[i].v;
pot[k]=pot[k]+1;//第k列的存放位置加1,准备存放地k列的下一个三元组
}
}
}
void main()
{
TSMatrix *p,*q;
inti,a[3][4]={{0,3,1,0},{1,0,0,0},{0,2,0,1}};
p=(TSMatrix *)malloc(sizeof(TSMatrix));
q=(TSMatrix *)malloc(sizeof(TSMatrix));
CreatMat(p,a,3,4);
printf(" i j data\n");
for(i=0;i<p->t;i++)
printf("%4d%4d%4d\n",p->data[i].i,p->data[i].j,p->data[i].v);
FastTranTat(p,q);
printf("After tsmatrix:\n");
printf(" i j data:\n");
for(i=0;i<q->t;i++)
printf("%4d%4d%4d\n",q->data[i].i,p->data[i].j,p->data[i].v);
}
矩阵转置
#include <stdio.h>
#include <stdlib.h>
#define MAXSIZE 30
typedef struct
{
int i;//行号
int j;//列号
int v;//非零元素值
}TNode;//三元组类型
typedef struct
{
int m;//矩阵行数
int n;//矩阵列数
int t;//矩阵中非零元素个数
TNode data[MAXSIZE];//三元组表
}TSMatrix;//三元组表类型
void CreatMat(TSMatrix *p,inta[3][4],int m,int n)//建立三元数组表
{
int i;
int j;
p->m=m;
p->n=n;
p->t=0;//p->t指向三元组表data的第一个三元组位置0
for(i=0;i<m;i++)
{
for(j=0;j<n;j++)
if(a[i][j]!=0)//将非零元素存储于三元组表data中
{
p->data[p->t].i=i;
p->data[p->t].j=j;
p->data[p->t].v=a[i][j];
p->t++;//下标加1使三元组表a 存放下一个非零元素
}
}
}
void TranTat(TSMatrix*a,TSMatrix *b)//在三元组表的存储方式下,实现矩阵的转置
{
int k,p,q;//k指向三元组表a的列号;p,q分别为指示三元组a和b的下标
b->m=a->m;
b->n=a->n;
b->t=a->t;
if(b->t!=0)//当三元组表不为空
{
q=0;//由三元组b的第一个三元组位置0开始
for(k=0;k<a->n;k++)//对三元组表a按下列下标由小到大进行扫描
{
for(p=0;p<a->t;p++)//按表长扫描整个三元组表
if(a->data[p].j==k)
{
b->data[q].i=a->data[p].j;
b->data[q].j=a->data[p].i;
b->data[q].v=a->data[p].v;
q++;
}
}
}
}
void main()
{
TSMatrix *p,*q;
inti,a[3][4]={{0,3,1,0},{1,0,0,0},{0,2,0,1}};
p=(TSMatrix *)malloc(sizeof(TSMatrix));//生成三元组表存储空间
q=(TSMatrix *)malloc(sizeof(TSMatrix));//生成转制后的三元组表存储空间
CreatMat(p,a,3,4);//生成矩阵的三元组表
printf("Befor tsmarix:\n");//输出三元组表
printf(" i j data\n");
for(i=0;i<p->t;i++)
printf("%4d%4d%4d\n",p->data[i].i,p->data[i].j,p->data[i].v);
TranTat(p,q);//进行矩阵的转置
printf("After tsmatrix:\n");
printf(" i j data\n");
for(i=0;i<q->t;i++)
printf("%4d%4d%4d\n",q->data[i].i,q->data[i].j,q->data[i].v);
}
生成广义表及求广义表长度、深度
#include <stdio.h>
#include <stdlib.h>
#define MAXSIZE 30
typedef struct
{
char data[MAXSIZE];
int top;
}SeqStack;//顺序栈类型
void Init_SeqStack(SeqStack**s)//顺序栈初始化
{
*s=(SeqStack *)malloc(sizeof(SeqStack));//在主调函数中申请栈空间
(*s)->top=-1;//置栈空标志
}
int Empty_SeqStack(SeqStack*s)//判栈空
{
if(s->top==-1)//栈为空时
return 1;
else
return 0;
}
void Push_SeqStack(SeqStack*s,char x)//元素入栈
{
if(s->top==MAXSIZE-1)
printf("Stack is full\n");//栈已满
else
{
s->top++;
s->data[s->top]=x;//元素x压入栈中
}
}
void Pop_SeqStack(SeqStack*s,char *x)//元素出栈
{
if(s->top==-1)
printf("Stack is empty!\n");//栈为空
else
{
*x=s->data[s->top];//栈顶元素出栈
s->top--;
}
}
void Top_SeqStack(SeqStack*s,char *x)//度栈顶元素
{
if(s->top==-1)
printf("Staack is empty!\n");
else
*x=s->data[s->top];
}
typedef struct node
{
int flag;//标志域
union//元素结点和表结点共用内存
{
char data;//元素结点数据域
struct node *hp;//表结点的头指针
}val;
struct node *tp;//指向下一个兄弟节点
}CBNode;//广义表结点类型
CBNode *Create(char ex[])//用孩子兄弟表示法建立广义表)
{
CBNode *p,*q=NULL,*h,*hp[MAXSIZE];//h为最终生成的广义表表头指针
SeqStack *s;
char x,*y=&x;//出栈元素经过指针y指向x
int i=0,j=0,b=0,t=0,k=0;
Init_SeqStack(&s);
while(ex[i]!='\0')//是否到表达式串的串尾
{
if(ex[i]==' ')//当前字符为空格字符是
i++;
if(ex[i]=='(')
{
Push_SeqStack(s,ex[i]);
p=(CBNode*)malloc(sizeof(CBNode));
p->flag=1;//新结点作为表头结点
p->tp=NULL;//表元素结点的tp指针暂置为空
k=0;//表元素结点标志
hp[j++]=p;//将指向表元素的指针p压入hp中
if(q!=NULL)
if(t==1)
{
t=0;
q->tp=p;//结点*p作为*q兄弟结点链入链表
}
else
q->val.hp=p;//结点*p作为*q孩子节点链入表中
else
q=p;//指针q下移指向结点*p
if(b==0)//刚生成的广义表的第一个结点
{
h=p;
b=1;//使广义表指针h指向该节点
}
}
else
if(ex[i]==')')//字表结束
{
Top_SeqStack(s,y);
if(*y=='(')
{
p->tp=NULL;
if(ex[i-1]=='('||(ex[i-1]==' '&&ex[i-2]=='('))//空表时的处理
p->val.hp=NULL;//子表是空表
Pop_SeqStack(s,y);
if(j!=0)//当栈hp未到栈底
{
q=hp[--j];//将保存于hp的表元素结点指针弹出赋给q
if(ex[i+1]==',')
{
if(ex[i+2]=='(')//下一个兄弟节点是表示元素结点的处理
{
t=1;k=0;i++;
goto 12;
}
i++;
}
k=1;//下一兄弟节点是氮元素结点的处理
12: ;
}
}
else
{
h=NULL;//输入的广义表字符串有错,置广义表为空
printf("Error!\n");
goto 11;
}
}
else
if(ex[i]!=',')//生成单元素结点的处理
{
if(k==0)//在此之前生成的*p为表元素结点
{
q=p;//使q指向这个表元素结点
k=0;
}
p=(CBNode*)malloc(sizeof(CBNode));//创建新节点
p->flag=0;//新结点作为单元素结点
p->val.data=ex[i];
if(ex[i-1]=='(')
q->val.hp=p;//作为孩子节点链接到当前节点上
else
q->tp=p;//作为兄弟节点连接到当前结点
}
else
{
q=p;
t=1;
}
i++;
}
if(!Empty_SeqStack(s))//栈s不为空则(与)不匹配,即输入串有错
{
h=NULL;
printf("Error!\n");
}
11: return h;//返回广义表头指针
}
int CBLength(CBNode *h)//求广义表的头指针
{
int n=0;
h=h->val.hp;//h指向广义表的第一个元素
while(h!=NULL)
{
n++;
h=h->tp;
}
return n;//n为广义表的长度
}
int CBDepth(CBNode *h)//求广义表的深度
{
int max=0,dep;//置深度初值为0
if(h->flag==0)//为单元素时返回0
return 0;
h=h->val.hp;//h指向广义表的第一个元素
if(h==NULL)//子表为空时返回1
return 1;
while(h!=NULL)//遍历表中的每一个元素
{
if(h->flag==1)//元素为表结点时
{
dep=CBDepth(h);//递归调用求出子表的深度
if(dep>max)//max为同一层所求子表中的深度最大值
max=dep;
}
h=h->tp;//使h指向下一个元素值
}
return max+1;//返回表的深度
}
void DispcB(CBNode *h)//输出广义表
{
if(h!=NULL)//表非空
{
if(h->flag==1)//为表结点时
{
printf("(");
if(h->val.hp==NULL)
printf(" ");//输出空子表
else
DispcB(h->val.hp);//递归输出子表
}
else
printf("%c",h->val.data);//为单元素时输出元素值
if(h->flag==1)
printf(")");
if(h->tp!=NULL)//有后继结点时
{
printf(",");//输出间隔符
DispcB(h->tp);//递归输出后继元素的结点信息
}
}
}
void main()
{
char c[MAXSIZE];
CBNode *h;//定义广义表类型指针变量h
printf("Input lists:\n");
gets(c);//输入广义表字符串
h=Create(c);//根据字符串建立广义表
DispcB(h);//输出广义表
printf("\n");
printf("Length of lists is%d\n",CBLength(h));//输出广义表长度
printf("Depth of lists is%d\n",CBDepth(h));//输出广义表的深度
}
稀疏矩阵的十字链表存储
#include <stdio.h>
#include <stdlib.h>
#define MAXSIZE 10
typedef struct node
{
int row,col;//row和col为非零元素所在的行和列
struct node *down,*right;//right和down为非零元素结点的行、列指针
union
{
int v;//v为非零元素的值
struct node *next;//next为头结点链表指针
}tag;
}MNode;//十字链表结点类型
void print(MNode *h[],intm,int n)//输出十字链表
{
MNode *p;
int i;
printf("十字链表的行链表:\n");
for(i=0;i<m;i++)
{
p=h[i]->right;
printf("H%d: ",i);
while(p!=h[i])
{
printf("(%d,%d):%d,",p->row,p->col,p->tag.v);
p=p->right;
}
printf("\n");
}
printf("十字链表的列链表:\n");
for(i=0;i<n;i++)
{
p=h[i]->down;
printf("H%d: ",i);
while(p!=h[i])
{
printf("(%d,%d):%d",p->row,p->col,p->tag.v);
p=p->down;
}
printf("\n");
}
}
void CreatMat(MNode**mh,MNode *h[])//建立稀疏矩阵的十字链表
{
MNode *p,*q;//p和q为暂存指针
int i,j,k,m,n,t,v,max;//设非零元素的值v为整形
printf("Input m,n,t:");
scanf("%d,%d,%d",&m,&n,&t);
*mh=(MNode *)malloc(sizeof(MNode));//创建头结点循环链表的头结点
(*mh)->row=m;//存储矩阵的行数
(*mh)->col=n;//存储矩阵的列数
p=*mh;//指针p指向头结点*mh
if(m>n)
max=m;//如果行数大雨列数则将行数值赋给max
else
max=n;//如果列数大雨行数将值赋给max
for(i=0;i<max;i++)//采用尾插法创建头结点
{
h[i]=(MNode *)malloc(sizeof(MNode));
h[i]->down=h[i];//初始时down指向头结点自身
h[i]->right=h[i];//初始时right指向头结点自身
h[i]->row=-1;
h[i]->col=-1;
p->tag.next=h[i];//降头结点连接起来形成一个链表
p=h[i];
}
p->tag.next=*mh;//将最后插入的头结点中的next指针再指向揽投形成头结点循环链表
for(k=0;k<t;k++)
{
printf("Input i,j,v:");
scanf("%d,%d,%d",&i,&j,&v);//输入一个三元组
p=(MNode *)malloc(sizeof(MNode));
p->row=i;
p->col=j;
p->tag.v=v;//以下实现将*p插入到底i行链表中区,且按列号有序
q=h[i];
while(q->right!=h[i]&&q->right->col<j);//按列号找到位置插入
q=q->right;
p->right=q->right;//完成插入
q->right=p;//以下实现将*p插入到第j列链表中去,且按行号有序
q=h[j];
while(q->down!=h[j]&&q->down->row<i)//按行号找到插入位置
q=q->down;
p->down=q->down;//完成插入
q->down=p;
}
print(h,m,n);//输出十字链表
}
void main()
{
MNode *mh,*h[MAXSIZE];
CreatMat(&mh,h);//建立十字链表
}