数据结构实验1

数据结构实验

          • 1.1 单链表插入删除
          • 1.2 约瑟夫环
          • 2.1 二进制转十进制
          • 2.2 表达式求值
          • 3.1 判断回文序列
          • 3.2 猴子分桃
          • 4.1 替换子串
          • 4.2 矩阵求和

1.1 单链表插入删除
//建立一个存储A,B... 26个大写英文字母的线性链表,插入或删除字母使其位于适当位置 
#define OK 1
#define NULL 0
#define OVERFLOW -2
#include 
#include  //exit()
#include
typedef char ElemType;
typedef int Status;
typedef struct LNode {
	ElemType data;
	struct LNode *next;
}LNode,*LinkList; 
 
LinkList CreateList(LinkList L)
{ //建立一个存储A,B... 26个大写英文字母的线性链表L
	LinkList p,r;
	char i;
	L=(LinkList)malloc(sizeof(LNode));
	if(!L) //存储分配失败
     exit(OVERFLOW);
	r=L;
	for(i='A';i<='Z';i++)
	{//存储初始数据元素为大写字母A到Z 
		p=(LNode*)malloc(sizeof(LNode));
		p->data=i;
		r->next=p;
		r=p;
	}
	r->next=NULL;
	return L;
}
LinkList ListInsert(LinkList L,ElemType e) 
{ //将元素e插入到单链表的适当位置上,以保持该表的有序性 
    int j=0;
    LinkList p=L->next,s;
	while(p&&j<26)
	{
		if(e>p->data) // 寻找适当的插入位置 
		{
		    p=p->next;
		}
		else break;
		j++;	     
	}
    s=(LinkList)malloc(sizeof(LNode)); // 生成新结点
    s->data=e; 
    s->next=p->next; //插入L中 
    p->next=s;
    return L;
}
LinkList ListDelete(LinkList L,ElemType e) 
{ //在单链线性表L中,删除元素e
	int j=0;
	LinkList p=L->next,q=L,r;
    while(p&&j<26)
	{
		if(e!=p->data) //找到第一个与e相同的元素 
		{
			q=p;
		    p=p->next;
		}
		else break;
		j++;	     
	}
	r=p;
    q->next=p->next;
    free(r); //释放结点 
    return L;
}
void visit(ElemType c)
{
	printf("%c ",c);
}
Status ListTraverse(LinkList L,void(*vi)(ElemType))
{ //遍历链表中元素 
   LinkList p=L->next;
   while(p)
   {
     vi(p->data);
     p=p->next;
   }
   printf("\n");
   return OK;
}
int main()
{
	LinkList L,L1,L2,L3;
	ElemType e1,e2;
	L1=CreateList(L);
	printf("初始单链表数据为:\n") ;
	ListTraverse(L1,visit);
	printf("\n"); 
	printf("请输入要插入的大写英文字母:");
	scanf("%c",&e1);
	printf("插入字母%c后单链表为:\n",e1);
	if(e1<'A'||e1>'Z')
	{
	 	printf("输入错误");
	}
	else{
		L2=ListInsert(L1,e1);
		ListTraverse(L2,visit);
	}
	printf("\n"); 
	printf("请输入要删除的大写英文字母:");
	fflush(stdin); 
	scanf("%c",&e2);
	printf("删除字母%c后单链表为:\n",e2);
	if(e2<'A'||e2>'Z')
	{
	 	printf("输入错误");
	}
	else{
		L3=ListDelete(L2,e2);
		ListTraverse(L3,visit);
	}
	return OK;
}
1.2 约瑟夫环
//约瑟夫环(循环链表) 
#define NULL 0
#define OVERFLOW -2 
#include
#include
#include
typedef struct LNode{
	int num; //每个人的编号 
	int data; //密码 
	struct LNode *next;
}LinkList;
LinkList *create(int n)
{ //建立单向循环链表 
	printf("请输入人数n:");
	scanf("%d",&n);
    printf("请分别输入这%d个人的密码:\n",n);
    int i=1;
    LinkList *L,*p,*q;
    L=NULL;
    p=(LinkList*)malloc(sizeof(LinkList));
    if(!p) //存储分配失败
     exit(OVERFLOW);
    p->num=1;
    scanf("%d",&p->data);
    L=p;
    for(i=2;i<=n;i++)
    {
    	q=(LinkList*)malloc(sizeof(LinkList));
    	if(!p) 
     		exit(OVERFLOW);
    	q->num=i;
    	scanf("%d",&q->data);
    	p->next=q;
    	p=q;
	}
	p->next=L; //指针域指向头结点
    return L;
}
void func(LinkList *L,int m)
{
	printf("请输入m的初值:");
	scanf("%d",&m);
	printf("依次出列的人的编号为:");
	int i,j;
	LinkList *p,*q,*s;
	p=L;
	while(p->next!=p) //直到只剩下最后一个结点 
	{
		for(j=1;jnext;
		}
		printf("%d",p->num); //输出出列的人的编号  
		m=p->data; //出列的人的密码作为新的m值 
		s=p;
		q->next=p->next; //删除出列的人的结点
		p=p->next;
		free(s);  //释放该结点 
	}
	printf("%d",p->num); //输出最后一个结点的人的编号 
	printf("\n");
}
int main()
{
	LinkList *L;
	int m,n;
	L=create(n);
	func(L,m);
	return 0;
}

2.1 二进制转十进制
//进制转换--二进制转为十进制 (栈) 
#define OK 1 
#define OVERFLOW -2 
#define ERROR 0
#define NULL 0
#define TRUE 1
#define FALSE 0
#define STACK_INIT_SIZE 20
#define STACKINCREMENT 10
#include 
#include // exit()
#include
typedef int SElemType;
typedef int Status;
typedef struct {
	SElemType *base;
	SElemType *top;
	int stacksize;
}SqStack;
Status InitStack(SqStack &S)
{ //构造一个空栈 
	S.base=(SElemType *)malloc(STACK_INIT_SIZE*sizeof(SElemType));
	if(!S.base) exit(OVERFLOW); //存储分配失败 
	S.top=S.base;
	S.stacksize=STACK_INIT_SIZE;
	return OK;
}
Status Push(SqStack &S,SElemType e)
{ //插入元素e为新的栈顶元素 
	if(S.top-S.base>=S.stacksize)
	{ //栈满,追加存储空间 
		S.base=(SElemType *)realloc(S.base,(S.stacksize+STACKINCREMENT)*sizeof(SElemType));
		if(!S.base) exit(OVERFLOW); //追加存储空间失败 
		S.top=S.base+S.stacksize;
		S.stacksize+=STACKINCREMENT;
	}
	*S.top=e;
	S.top++; //栈顶指针后移 
	return OK;
}
Status Pop(SqStack &S,SElemType &e)
{ //删除栈顶元素,用e返回其值 
	if(S.top==S.base) //栈空,返回ERROR 
 		return ERROR;
	S.top--;  
	e=*S.top;
	return OK;
}
Status DestroyStack(SqStack &S)
{ //销毁栈S,S不再存在
	free(S.base);
	S.base=NULL;
	S.top=NULL;
	S.stacksize=0;
	return OK;
}
Status StackEmpty(SqStack S)
{ //若栈S为空栈,则返回TRUE,否则返回FALSE
	if(S.top==S.base)
		return TRUE;
	else return FALSE;
}
int main()
{
	SqStack s;
	int n; 
	SElemType e;
	InitStack(s); 
	printf("请输入一非负十进制整数n:");
	scanf("%d",&n); 
	if(n<=0) printf("输入错误"); //输入不合法
	else
	{
		while(n) //当n不等于0
		{
			e=n%2;
			Push(s,e); //入栈n除以2的余数
			n=n/2;
		}
		printf("转换成二进制数为:");
		while(!StackEmpty(s)) //栈非空 
		{
			Pop(s,e);   //弹出栈顶元素且赋值给e 
			printf("%d",e);   //输出e
		}
		printf("\n"); 
	} 
	DestroyStack(s); 
	return 0;
}

2.2 表达式求值
//表达式求值(两个栈) 
#define OK 1 
#define OVERFLOW -2 
#define ERROR 0
#define NULL 0
#define TRUE 1
#define FALSE 0
#define STACK_INIT_SIZE 20
#define STACKINCREMENT 10
#include //malloc()等
#include //exit()
#include
typedef char SElemType;
typedef int Status;
typedef struct {
	SElemType *base;
	SElemType *top;
	int stacksize;
}SqStack;
Status InitStack(SqStack &S)
{ //构造一个空栈 
	S.base=(SElemType *)malloc(STACK_INIT_SIZE*sizeof(SElemType));
	if(!S.base) exit(OVERFLOW); //存储分配失败 
	S.top=S.base;
	S.stacksize=STACK_INIT_SIZE;
	return OK;
}
Status Push(SqStack &S,SElemType e)
{ //插入元素e为新的栈顶元素
	if(S.top-S.base>=S.stacksize)
	{ //栈满,追加存储空间
		S.base=(SElemType *)realloc(S.base,(S.stacksize+STACKINCREMENT)*sizeof(SElemType));
		if(!S.base) exit(OVERFLOW);
		S.top=S.base+S.stacksize;
		S.stacksize+=STACKINCREMENT;
	}
	*S.top=e;
	S.top++; //栈顶指针后移
	return OK;
}
Status Pop(SqStack &S,SElemType &e)
{ //删除栈顶元素,用e返回其值
	if(S.top==S.base) //栈空,返回ERROR
		return ERROR;
	S.top--;
	e=*S.top;
	return OK;
}
Status GetTop(SqStack S,SElemType &e)
{ //用e返回S的栈顶元素 
	if(S.top==S.base) return ERROR; //栈空,返回ERROR 
	e=*(S.top-1);
	return OK;
}
Status DestroyStack(SqStack &S)
{ //销毁栈S,S不再存在
	free(S.base);
	S.base=NULL;
	S.top=NULL;
	S.stacksize=0;
	return OK;
}
Status StackEmpty(SqStack S)
{ //若栈S为空栈,则返回TRUE,否则返回FALSE
	if(S.top==S.base)
		return TRUE;
	else return FALSE;
}
Status In(SElemType c)
{ //判断c是否为运算符
	switch(c)
	{
		case'+':
     	case'-':
     	case'*':
     	case'/':
     	case'(':
     	case')':
     	case'#':return TRUE;
     	default:return FALSE;
   	}
}
char OP[7]={'+','-','*','/','(',')','#'};
char precede[7][7]={
'>','>','<','<','<','>','>',
'>','>','<','<','<','>','>',
'>','>','>','>','<','>','>',
'>','>','>','>','<','>','>',
'<','<','<','<','<','=',0,
'>','>','>','>',0,'>','>',
'<','<','<','<','<',0,'='};
/*************************对数据操作符数组OP及优先权矩阵的定义*/

/*************************判断输入字符是否为操作符,否则将其认为是数字*/
char Precede(char op,char c)
{
	int pos_op;
	int pos_c;
	int i;
	for (i=0;i<7;i++)
	{
		if(op==OP[i]) pos_op=i;
		if(c==OP[i]) pos_c=i;
	}
	return(precede[pos_op][pos_c]);
}
/*************************对判定为操作符的字符根据优先权矩阵判断其优先顺序*/
char Operate(char a,char theta,char b)
{
	switch(theta)
	{   
		case '+': return a+b-'0';
		case '-': return a-b+'0';
		case '*': return (a-'0')*(b-'0')+'0';
		case '/': return (a-'0')/(b-'0')+'0';
	}
}
/*************************对表达式进行计算,返回计算结果*/

SElemType EvaluateExpression() 
{ //算术表达式求值的算符优先算法,OPTR和OPND分别为运算符栈和运算数栈
	SqStack OPTR,OPND;
   	SElemType a,b,c,x,theta;
   	int i=-1,u=0,m,n[20];
   	InitStack(OPTR);
   	Push(OPTR,'#');
   	InitStack(OPND);
   	c=getchar();
   	GetTop(OPTR,x);
   	while(c!='#'||x!='#')
   	{
		if(In(c)) //c为7种运算符之一
       	switch(Precede(x,c))
       	{
			case'<':Push(OPTR,c); //栈顶元素优先权低
                 	c=getchar();
                 	break;
         	case'=':Pop(OPTR,x); //脱括号并接收下一字符
                 	c=getchar();
                 	break;
         	case'>':Pop(OPTR,theta); //退栈并将运算结果入栈
		 			Pop(OPND,b);
                 	Pop(OPND,a);
                 	Push(OPND,Operate(a,theta,b));
                 	break;
       	}
		else if(c>='0'&&c<='9') //c为操作数
     	{
			Push(OPND,c);
       		c=getchar();
     	}
     	GetTop(OPTR,x);
   	}
   	GetTop(OPND,x);
   	DestroyStack(OPTR); 
   	DestroyStack(OPND);
   	return x;
}
int main()
{	
	char i;
	printf("请输入算术表达式,并以#结束:\n");
	i=EvaluateExpression();
	printf("该表达式的结果为: ");
	printf("%d\n",i-'0');
	return 0;
}

3.1 判断回文序列
//判断回文序列(一个栈和一个循环队列)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   //判断回文序列 
#define MAXSTRLEN 255 
#define OK 1 
#define OVERFLOW -2 
#define ERROR 0
#define TRUE 1
#define FALSE 0
#define STACK_INIT_SIZE 20
#define STACKINCREMENT 10
#define MAXQSIZE 5 //最大队列长度
#include 
#include // exit()
#include
typedef char SElemType;
typedef char QElemType;
typedef int Status;
typedef unsigned char SString[MAXSTRLEN+1];
typedef struct {
	SElemType *base;
	SElemType *top;
	int stacksize;
}SqStack;
struct SqQueue
{
	QElemType *base; //初始化的动态分配存储空间
	int front; //头指针,若队列不空,指向队列头元素
	int rear; //尾指针,若队列不空,指向队列尾元素的下一个位置
};
Status InitStack(SqStack &S)
{ //构造一个空栈
	S.base=(SElemType *)malloc(STACK_INIT_SIZE*sizeof(SElemType));
	if(!S.base) exit(OVERFLOW); //存储分配失败 
	S.top=S.base;
	S.stacksize=STACK_INIT_SIZE;
	return OK;
}
Status Push(SqStack &S,SElemType e)
{ //插入元素e为新的栈顶元素
	if(S.top-S.base>=S.stacksize)
	{ //栈满,追加存储空间 
		S.base=(SElemType *)realloc(S.base,(S.stacksize+STACKINCREMENT)*sizeof(SElemType));
		if(!S.base) exit(OVERFLOW);
		S.top=S.base+S.stacksize;
		S.stacksize+=STACKINCREMENT;
	}
	*S.top=e;
	S.top++; //栈顶指针后移
	return OK;
}
Status Pop(SqStack &S,SElemType &e)
{ //删除栈顶元素,用e返回其值
	if(S.top==S.base) //栈空,返回ERROR 
		return ERROR;
	S.top--;
	e=*S.top;
	return OK;
}
Status DestroyStack(SqStack &S)
{ //销毁栈S,S不再存在
	free(S.base);
	S.base=NULL;
	S.top=NULL;
	S.stacksize=0;
	return OK;
}
Status StackEmpty(SqStack S)
{ //栈S为空栈,则返回TRUE,否则返回FALSE
	if(S.top==S.base)
		return TRUE;
	else return FALSE;
}
Status InitQueue(SqQueue &Q)
{ //构造一个空队列Q 
	Q.base=(QElemType *)malloc(MAXQSIZE*sizeof(QElemType));
	if(!Q.base) exit(OVERFLOW); //存储分配失败 
	Q.front=Q.rear=0;
	return OK;
}
Status EnQueue(SqQueue &Q,QElemType e)
{//插入元素e为Q的新的队尾元素 
	if(Q.rear>=MAXQSIZE) 
	{ //队列满,追加存储空间 
		Q.base=(QElemType *)realloc(Q.base,(Q.rear+1)*sizeof(QElemType));
		if(!Q.base) return ERROR; //追加存储空间失败
	}
	*(Q.base+Q.rear)=e;
	Q.rear++;
	return OK;
}
Status ClearQueue(SqQueue &Q)
{ //将Q清为空队列 
	Q.front=Q.rear=0;
	return OK;
}
Status QueueEmpty(SqQueue Q)
{ //若Q为空队列,则返回TRUE,否则返回FALSE
	if(Q.front==Q.rear)
		return TRUE;
	else
		return FALSE;
}
Status DeQueue(SqQueue &Q,QElemType &e)
{ //删除Q的队尾元素,用e返回其值
	if(Q.front==Q.rear) return ERROR; //队列空,返回ERROR 
	e=Q.base[Q.front];
	Q.front=Q.front+1;
	return OK;
}
int main()
{//判断是否是回文序列 
	SqStack s;
	InitStack(s);
	SqQueue q;
	InitQueue(q);
	printf("请输入所要判断的序列:");
	char a[20];
	int i=0,j=0;
	SElemType b;
	QElemType c;
	while(scanf("%c",&a[i])&&a[i]!='\n') //输入序列元素,回车'\n'表示结束 
	{
		Push(s,a[i]);   //入栈 
		EnQueue(q,a[i]);  //入队列 
		i++;
	}
	while(!StackEmpty(s)&&!QueueEmpty(q))
	{
		Pop(s,b);
		DeQueue(q,c);
		if(b!=c)
		{ //一旦出现不相等的情况,跳出while循环 
			printf("判断结果:该序列不是回文序列.\n");
			break;  
		}
		j++; //j用来计数,即b和c相等的个数 
	}
	if(j==i) //j等于序列元素总个数i,即所有对应的b和c都相同 
	{
		printf("判断结果:该序列是回文序列.\n");
	}
	return 0;
} 

3.2 猴子分桃
//猴子分桃问题 (队列)
#define OK 1 
#define OVERFLOW -2 
#define ERROR 0
#define NULL 0
#define TRUE 1
#define FALSE 0
#include 
#include //exit()
#include
typedef int QElemType;
typedef int Status;
typedef struct QNode{
	QElemType id;   //猴子编号 
	QElemType Peach_num;   //猴子拥有的桃子数 
	struct QNode *next;
}QNode,*QueuePtr;
struct LinkQueue
{
	QueuePtr front,rear; //队头、队尾指针
};
Status InitQueue(LinkQueue &Q)
{ //构造一个空队列Q
	Q.front=Q.rear=(QueuePtr)malloc(sizeof(QNode));
	if(!Q.front)  //存储分配失败 
		exit(OVERFLOW);
	Q.front->next=NULL;
    return OK;
}
Status ClearQueue(LinkQueue &Q)
{ //将Q清为空队列
	QueuePtr p,q;
    Q.rear=Q.front;
   	p=Q.front->next;
   	Q.front->next=NULL;
   	while(p)
   	{
		q=p;
     	p=p->next;
     	free(q);
   	}
   	return OK;
}
Status QueueEmpty(LinkQueue Q)
{ //若Q为空队列,则返回TRUE,否则返回FALSE
	if(Q.front==Q.rear)
		return TRUE;
	else
		return FALSE;
}
Status EnQueue(LinkQueue &Q,int i,int pea)
{ //插入猴子编号为i,拥有桃子数为pea的结点为Q的新的队尾元素
	QueuePtr p;
	p=(QueuePtr)malloc(sizeof(QNode));
   	if(!p)  //存储分配失败
		exit(OVERFLOW);
   	p->id=i;
   	p->Peach_num=pea;
   	p->next=NULL;
   	Q.rear->next=p;
   	Q.rear=p;
   	return OK;
}
Status DeQueue(LinkQueue &Q,int &i,int &pea)
{ //删除Q的队头元素,并用i,pea分别返回猴子编号和拥有桃子数 
	QueuePtr p;
   	if(Q.front==Q.rear) //队列空,返回ERROR 
		return ERROR;
   	p=Q.front->next;
   	i=p->id;
   	pea=p->Peach_num;
   	Q.front->next=p->next;
   	if(Q.rear==p)
		Q.rear=Q.front;
   	free(p);
   	return OK;
}
int main()
{
	LinkQueue Monkey;
	QElemType mon;
	QueuePtr p,q;
	int a,b,Person_Peach,Box_Peach=0;  //起始筐中桃子数为0 
	InitQueue(Monkey);  //初始化一个猴子队列 
	int n,k,m,j=0;
	printf("请依次输入初始条件n、k和m(中间用空格隔开):");
	scanf("%d %d %d",&n,&k,&m);
	printf("即初始条件为:\n");
	printf("  共有%d只猴子\n",n);
	printf("  每次最多取%d个桃到筐中\n",k);
	printf("  每只猴子最终都分到%d个桃子\n\n",m);
	int c[n];  //定义一数组用来记录依次出队的猴子编号 
	for(int i=1;i<=n;i++)
	{
		EnQueue(Monkey,i,0);  //起始猴子拥有的桃子数均为0 
	} 
	p=Monkey.front->next; //p为队首猴子 
	while(!QueueEmpty(Monkey))
	{ //猴子队列非空,饲养员放入筐中的桃子数从1到k循环 
		for(Person_Peach=1;Person_Peach<=k;Person_Peach++)
		{ 
			if(p) //若p非空,继续进行;若p空,再进行判断和for循环无意义,跳出for循环 
			{  
				if(p->Peach_num+Person_Peach+Box_PeachPeach_num=p->Peach_num+Person_Peach+Box_Peach;
					a=p->id;
					b=p->Peach_num;
					DeQueue(Monkey,p->id,p->Peach_num); //当前猴子出队 
					EnQueue(Monkey,a,b);  //猴子取得的小于m,出队猴子再入队 
					p=Monkey.front->next;
				}
				else
				{ //猴子取得的大于等于m 
					printf("出列的猴子编号为:%d\n",p->id);
					c[j]=p->id;
					j++;
					Box_Peach=Box_Peach+p->Peach_num+Person_Peach-m; //大于m的部分为筐中剩余 
					DeQueue(Monkey,p->id,p->Peach_num);  //取满m个桃子的猴子离开队列
					printf("筐中此时的桃子数为:%d\n\n\n",Box_Peach);
					p=Monkey.front->next;
				}
			}
			else break; //p空,即猴子已全部出列,跳出for循环 
		}
	}
	printf("出列的猴子编号依次为:");
	for(int t=0;t
4.1 替换子串
//替换子串(串的相关操作) 
#define OK 1 
#define OVERFLOW -2 
#define ERROR 0
#define NULL 0
#define TRUE 1
#define FALSE 0
#include  //malloc()、realloc() 
#include //exit()
#include
#include //strlen() 
typedef int Status;
typedef struct {  //串的堆分配存储 
	char *ch; //若是非空串,则按串长分配存储区,否则ch为NULL 
	int length; //串长度 
}HString;
Status StrAssign(HString &T,char *chars)
{ //生成一个其值等于串常量chars的串T
	int i,j;
    if(T.ch)  //释放T原有空间
      free(T.ch);
    i=strlen(chars); //求chars的长度i
    if(!i)
    { //chars的长度为0
      T.ch=NULL;
      T.length=0;
    }
    else
    { //chars的长度不为0
      T.ch=(char*)malloc(i*sizeof(char)); //分配串空间
      if(!T.ch)    //分配串空间失败
        exit(OVERFLOW);
      for(j=0;jT,则返回值>0;若S=T,则返回值=0;若SS.length||len<0||len>S.length-pos+1)  //输入不合法 
    	return ERROR;
	if(Sub.ch)
    	free(Sub.ch); //释放旧空间
	if(!len) //空子串
	{
    	Sub.ch=NULL;
    	Sub.length=0;
	}
	else
	{ //非空子串
    	Sub.ch=(char*)malloc(len*sizeof(char));
    	if(!Sub.ch)    //分配空间失败 
    		exit(OVERFLOW);
    	for(i=0;i<=len-1;i++)    //拷贝该子串 
    		Sub.ch[i]=S.ch[pos-1+i];
    	Sub.length=len;
    }
   	return OK;
}
Status StrEmpty(HString S)
{ //若S为空串,则返回TRUE,否则返回FALSE
	if(S.length==0&&S.ch==NULL)
		return TRUE;
	else
		return FALSE;
}
void StrPrint(HString T)
{ //输出字符串T
	int i;
	for(i=0;i=m)
					{ //替换字符串r长度大于等于被替换子串t
						s.ch=(char*)realloc(s.ch,(s.length+k-m)*sizeof(char));
						for(int j=s.length-1;j>=i+m-1;--j) //为插入r而腾出位置,后面子串后移适当长度
							s.ch[j+k-m]=s.ch[j];
    					for(int j=0;j
4.2 矩阵求和
//矩阵求和 
#define OK 1 
#define OVERFLOW 3
#define ERROR -1
#define NULL 0
#define TRUE 1
#define FALSE 0
#define MAXSIZE 12500
#include 
#include //exit()
#include
#include 
typedef int ElemType;
typedef int Status;
typedef struct{ //稀疏矩阵三元组顺序表存储 
	int i,j;  //该非零元的行下标和列下标 
	ElemType e;  //非零元的值 
}Triple;
typedef struct{
	Triple data[MAXSIZE+1]; //非零元的三元组表,data[0]未用 
	int mu,nu,tu;   //矩阵的行数、列数和非零元个数 
}TSMatrix;
Status CreateSMatrix(TSMatrix &M)
{ //创建稀疏矩阵M
	int i,m,n;
	ElemType x;
	Status k;
	printf("输入时请用空格隔开\n");
	printf("请输入矩阵的行数、列数和非零元个数:");
	scanf("%d %d %d",&M.mu,&M.nu,&M.tu);
	M.data[0].i=0; //为以下比较顺序做准备
	for(i=1;i<=M.tu;i++)
	{
		printf("请输入第%d个非零元所在的行,列,元素值:",i);
		fflush(stdin);
		scanf("%d %d %d",&m,&n,&x);
		M.data[i].i=m;
		M.data[i].j=n;
		M.data[i].e=x;
	}
	printf("\n"); 
	return OK;
}
Status AddSMatrix(TSMatrix M,TSMatrix N,TSMatrix &Q)
{ //求稀疏矩阵的和Q=M+N 
	if(M.mu!=N.mu||M.nu!=N.nu) //M和N的行数和列数必须对应相等 
		return ERROR;
	Q.mu=M.mu;
	Q.nu=M.nu;
	Q.tu=0;
	int t=1;
	for(int k=1;k<=M.tu;k++)
	{ //对M中的每个非零元进行判断,看它在N中是否有行列相同的非零元 
		int count=0;  //若该非零元在N中有对应行和列完全相同的非零元,count=1,否则count=0 
		for(int l=1;l<=N.tu;l++)
		{  //将该非零元与N中的所有非零元依次比较 
			if(M.data[k].i==N.data[l].i&&M.data[k].j==N.data[l].j)
			{  
				Q.data[t].i=M.data[k].i;
				Q.data[t].j=M.data[k].j;
				Q.data[t].e=M.data[k].e+N.data[l].e;
				if(Q.data[t].e!=0)
				{
					t++;
					Q.tu++; //若和不为0,结果矩阵Q非零元个数+1 
				}
				N.data[l].e=0; //对矩阵N中已加过的做标记 
				count=1;
			}
		}
		if(count==0)  
		{  //该非零元在N中无对应行和列完全相同的非零元,直接将该非零元赋给Q
			Q.data[t].i=M.data[k].i;
			Q.data[t].j=M.data[k].j;
			Q.data[t].e=M.data[k].e;
			t++;
			Q.tu++; //Q非零元个数+1 
		}
	}
	for(int l=1;l<=N.tu;l++)
	{
		if(N.data[l].e!=0)
		{ //除去N中被标记的,即对于N中剩余未加过的,直接赋给Q 
			Q.data[t].i=N.data[l].i;
			Q.data[t].j=N.data[l].j;
			Q.data[t].e=N.data[l].e;
			t++;
			Q.tu++;
		}
	}
	return 0;
}
void PrintSMatrix(TSMatrix M)
{ //输出稀疏矩阵M,构造一个与M相同的矩阵D
  //将D中的三元组转换成按行和列顺序排列的三元组 
	TSMatrix D;
	D.mu=M.mu;
	D.nu=M.nu;
	D.tu=0;
	for(int f=1;f<=M.tu;f++)
	{ //拷贝矩阵M 
		D.data[f].i=M.data[f].i;
		D.data[f].j=M.data[f].j;
		D.data[f].e=M.data[f].e;
		D.tu++;
	}
	int i;
	for(int k=1;k<=D.tu;k++)
	{
		for(int e=k+1;e<=D.tu;e++)
		{ //将当前D.data[k]的行,列与后面所有非零元的行,列依次比较 
			if(D.data[k].i>D.data[e].i)
			{ //行数小的排前面 
				D.data[0]=D.data[e]; //data[0]作为中转,完成data[e]和data[k]的交换 
				D.data[e]=D.data[k];
				D.data[k]=D.data[0];
			}
			if(D.data[k].i==D.data[e].i&&D.data[k].j>D.data[e].j)
			{ //行相同的情况下比较列,列数小的排前面 
				D.data[0]=D.data[e];
				D.data[e]=D.data[k];
				D.data[k]=D.data[0];
			}
		}
	} //排序完成,此时D为按行和列顺序排列的三元组 
	printf("结果矩阵C有%d行%d列%d个非零元素\n",D.mu,D.nu,D.tu);
	printf("矩阵C如下:\n");
	int t=1;
	 for(int i=1;i<=D.mu;i++)
	 {
	 	printf("     "); 
	 	for(int j=1;j<=D.nu;j++)
	 	{
	 		if(i==D.data[t].i&&j==D.data[t].j)
			{
				printf("%4d",D.data[t].e);
				t++;
			}
			else printf("%4d",0);  
		}
		printf("\n");
	 }
}
int main()
{
	TSMatrix A,B,C;
   	printf("创建矩阵A: \n");
   	CreateSMatrix(A);
   	printf("创建矩阵B: \n");
   	CreateSMatrix(B);
   	AddSMatrix(A,B,C);
   	printf("矩阵A和B相加,得结果矩阵C\n");
   	PrintSMatrix(C);
	return 0;
}

你可能感兴趣的:(我的存储)