数据结构之数组的部分逻辑结构

1、建立十字链表
2、输出十字链表
3、把十字链表转换为三元矩阵
4、打印三元矩阵
5、转置三元矩阵
#include "stdio.h"
#include "stdlib.h"
#include "string.h"
/*
2020/4/27   By:lnh 
*/
#define smax 30
typedef int datatype;
typedef struct lnode{
	int i,j;	//非零元素行,列 
	struct lnode *rptr,*cptr; //行和列的表头 
	union{
		struct lnode *next;
		datatype v;
	}uval;
}link;//十字链表 
typedef struct{
	int i,j;	//行,列 
	datatype v;	//值 
}node;
typedef struct{
	int m,n,t;//总行,总列,总非零元个数 
	node *data[smax];
}spmatrix;//三元组存储 

//函数声明
link *createlinkmat();
int printlinkmat(link *h);
spmatrix *changemat(link *h);
int printmat(spmatrix *a);
spmatrix *transmat(spmatrix *a);

//主函数 
int main(void)
{
	link *h;
	spmatrix *a,*b;
	
	//建立十字链矩阵
	h = createlinkmat();
	
	//输出十字链矩阵 
	printlinkmat(h);
	
	//把十字链矩阵转换为三元组矩阵
	a = changemat(h);
	
	//打印三元组矩阵
	printmat(a);
	
	//转置三元组矩阵 
	b = transmat(a);
	
	//输出转置后的矩阵 
	printmat(b); 
}
//建立十字链矩阵
link *createlinkmat(){
	link *head,*head_rowAndColum,*A[smax],*node_data,*temp;
	int row,column,num,tims,i,max,k;
	datatype val;
	//输入数组行,列,非零元素个数
	printf("请输入该数组行,列,非零元素个数:\n输入格式:4 5 9\n"); 
	scanf("%d %d %d",&row,&column,&num);
	getchar();	//接收回车符,防止下次输入的干扰 
	//检测输入是否合法 
	if((row<=0)||(column<=0)||(num<=0))
		return NULL;
	//创建总表头 
	head = (link*)malloc(sizeof(link));
	head->i = row;
	head->j = column;
	k = 0;	//记录非零元素的个数 
	A[0] = head;//总表域 
	if(row>column)
		max =  row;
	else
		max = column;
	//创建行和列的表头
	for(i=1;i<=max;i++){
		head_rowAndColum = (link*)malloc(sizeof(link));
		head_rowAndColum->i = 0;
		head_rowAndColum->j = 0;
		head_rowAndColum->rptr = head_rowAndColum;//行表头 
		head_rowAndColum->cptr = head_rowAndColum;//列表头 
		A[i] = head_rowAndColum;
		A[i-1]->uval.next = head_rowAndColum; 
	}
	//形成循环行表
	A[max]->uval.next = head;
	//形成非零元素链表
	printf("请输入该数组行,列,元素的值:(以Ctrl+Z结束)\n输入格式:4 5 9\n");		
	while((scanf("%d %d %d",&row,&column,&val))!=EOF){//输入非零元素 
		k++;
		if(k>num){
			printf("本次创建十字链表失败,请仔细检查并重新创建\n");
			return NULL; 
		}
		node_data = (link*)malloc(sizeof(link));
		node_data->i = row;
		node_data->j = column;
		node_data->uval.v = val;
		//查找行 
		temp = A[row];
		while((temp->rptr!=A[row])&&(temp->rptr->j<column))
		//temp的行已经有非零值并且temp的下一个节点的列小于输入的值 
			temp = temp->rptr; //temp指向这一行的下一个节点 
		node_data->rptr = temp->rptr;
		temp->rptr = node_data;
		//查找列 
		temp = A[column];
		while((temp->cptr!=A[column])&&(temp->cptr->i<row))
		//temp的列已经有非零值并且temp的下一个节点的行小于输入的值 
			temp = temp->cptr; //temp指向这一列的下一个节点 
		node_data->cptr = temp->cptr;
		temp->cptr = node_data; 
	}

	head = A[0];
	return head; 
}
//输出十字链矩阵
int printlinkmat(link *h){
	int row,column,max,i;
	link *head,*temp;
	if(h==NULL)	
		return 0;
	row = h->i;
	//copy the value of h 
	head = (link*)malloc(sizeof(link));
	head = h;
	//打印十字列表
	printf("十字列表格式(行,列,值):\n");
	for(i=1;i<=row;i++){
		//指向下一行的表头 
		head = head->uval.next;
		//临时变量,不能用free函数,否则head指针也清楚了 
		temp = (link*)malloc(sizeof(link));
		temp = head;
		//打印数据 
		while(temp->rptr->i!=0){
			temp = temp->rptr;
			printf("( %d,%d,%d)\n",temp->i,temp->j,temp->uval.v);
		}
	}
	return 1;
}
//把十字链矩阵转换为三元组矩阵
spmatrix *changemat(link *h){
	spmatrix *three;
	node *data_three;
	link *p,*temp;
	int i,k;
	three = (spmatrix*)malloc(sizeof(spmatrix)); 
	three->m = h->i;	//行 
	three->n = h->j;	//列 
	p = (link*)malloc(sizeof(link));
	p = h;	//copy h 
	k = 0;	//记录非零元素个数 
	for(i=1;i<=three->m;i++){	//按行进行扫描 
		//指向下一行的表头 
		p = p->uval.next;
		temp = (link*)malloc(sizeof(link));
		temp = p->rptr;	//指向p表头所在的行 
		while(temp->i!=0){	//将p这一行的非零值给三元矩阵 
			k++;
			data_three = (node*)malloc(sizeof(node));
			data_three->i = temp->i;
			data_three->j = temp->j;
			data_three->v = temp->uval.v;
			//将该节点存入三元组中 
			three->data[k] = data_three;
			//指向这一行的下一个元素 
			temp = temp->rptr;
		}
	}
	//记录总个数 
	three->t = k;
	return three;
}
//打印三元组矩阵
int printmat(spmatrix *a){
	spmatrix *three;
	node data_node;
	int k,n,row,colume;
	three = (spmatrix*)malloc(sizeof(spmatrix));
	three = a;
	k = three->t;
	n = 0;
	row = a->m;
	colume = a->n;
	int arr[row][colume];
	//将矩阵存入二维数组中 
	memset(arr,0,sizeof(arr)); //将数组值全置为零 
	//打印三元组 
	printf("三元组是:(行,列,值)\n(");
	while(n<k){
		n++;
		arr[three->data[n]->i-1][three->data[n]->j-1] = three->data[n]->v;
		printf("(%d, %d, %d)",three->data[n]->i,three->data[n]->j,three->data[n]->v);
	}
	printf(")\n");
	//打印矩阵 
	printf("矩阵是:\n"); 
	for(n=0;n<row;n++){
		for(k=0;k<colume;k++)
			printf(" %d ",arr[n][k]);
		printf("\n");
	}	
	return 1;
}
//转置三元组矩阵 
spmatrix *transmat(spmatrix *a){
	spmatrix *b;
	node *temp;
	int i = 1;
	b = (spmatrix*)malloc(sizeof(spmatrix));
	b->m = a->n;
	b->n = a->m;
	b->t = a->t;
	//将a的行和列互换形成一个新的三元组 
	while(i<=b->t){
		temp = (node*)malloc(sizeof(spmatrix));
		temp->i = a->data[i]->j;
		temp->j = a->data[i]->i;
		temp->v = a->data[i]->v;
		b->data[i] = temp;
		i++;
	}
	return b;
}

运行结果图:
结果图

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值