数组(array),在c语言里是最早接触到的数据结构。但是如果作为数据结构这门课来学,在c中学到的关于它的知识,还不足够。

数组的分类:
按物理结构来看,数组分为顺序结构和链式结构。
在顺序结构里,即便是多维数组(矩阵,Matrix),它还是按一维的形式存放在一组连续的存储空间里(别无他选)。一般有两种实现方法:按行顺序存储,称为以行为主(Row Major Order)。c、PASCAL等都采用这种方式。
按列顺序存储,称为以列为主(Column Major Order),FORTRAN使用这种结构。

数组还分为静态存储和动态存储。
静态的就是,int array[10] = {……};这种。
动态存储的是,int * array = new int[10];这一种。动态存储的区别就在于,是实例化后,才分配空间的,是动态地建立和撤销。

矩阵的存储:
矩阵的存储,可以是像每个元素都有独立的空间,还有一种就是压缩存储。即是对为多个值相同的元素,只分配一个存储空间,对零元素不分配空间。这是压缩存储的定义,也是我们在设计程序的效果体现。
如果值相同的元素或者零元素,在矩阵中的分布有一定额规律,即称为特殊矩阵反之为稀疏矩阵(Sparse Matrix )。
对称矩阵、三角矩阵、三对角矩阵都算是特殊矩阵。设计他们的压缩存储,其实思路不难。
稀疏矩阵的压缩存储,有三元组表,和链式结构的十字链表(Orthogonal List)。三元组表,即是(x坐标,y坐标,val值),只有有数值的才存储,0元素就不存储。这种方法在进行转置运算等非零个数在运算中保持不变时,有效。
但是在做加减等运算时,非零元素位置会变化,不适合三元组表。一般采用十字链表结构。不过,好像正统的定义是,每一行每一列都做一个链表,m行n列则需要m x n个链表了。而且每一个结点是由5个域组成:行域(row)、列域(column)、值域(val)、向下域(down)、向右域(right)。每个域都要有相应的值。
我在设计的时候,没认真看,以为总共row一个链表,column一个链表。就只有两个。

以下程序就算是半成品的十字链表吧:

结点的结构体类型和整个十字链表的结构体类型

typedef struct Olnode{
	int row,column;
	elementype val;
	struct Olnode * right;
	struct Olnode *down;
}Olnode ,*Olchain;

typedef struct Crosschain{
	int rownum,colnum;
	struct Olink *rowhead, * colhead;
}Crosschain;

各个函数:

void  insertNodeColumn(Olchain colhead,elementype val,int column); 
void  insertNodeRow(Olchain rowhead,elementype val,int row); 
void insertCrossChain(Crosschain * CrossChain,elementype val,int row,int column);

void printNode(Crosschain * CrossChain);
void printColumn(Olchain colhead);
void printRow(Olchain rowhead);


void deleteNode(Crosschain * CrossChain,elementype val);
void deleteNodeColumn(Olchain colhead,elementype val);
void deleteNodeRow(Olchain rowhead,elementype val);

void destroyChain(Crosschain * CrossChain);
void destroyColumn(Olchain colhead); 
void destroyRow(Olchain rowhead);

插入函数:

void insertCrossChain(Crosschain * CrossChain,elementype val,int row,int column)
{
	insertNodeColumn(CrossChain->colhead,val,column);
	insertNodeRow(CrossChain->rowhead,val,row);
	printf("insert the  CrossChain is succeed\n");
	
} 


void  insertNodeColumn(Olchain colhead,elementype val,int column)
{
	Olchain NodetoColumn = (Olnode *)malloc(sizeof(Olnode));
	NodetoColumn->val = val;
	NodetoColumn->column = column;
	NodetoColumn->right = NULL;
	
	Olchain TempNode = colhead;
	
	while(TempNode->right != NULL){
		if((TempNode->column < column) &&((TempNode->right->column > column)|(TempNode->right->column == column))){
			NodetoColumn->right = TempNode->right;
			TempNode->right = NodetoColumn;
		}
		else{
			TempNode = TempNode->right;
		}
	}
	if(TempNode->right == NULL){
		NodetoColumn->right = TempNode->right;
			TempNode->right = NodetoColumn;
	}
	printf("insert the column is succeed\n");

}

void  insertNodeRow(Olchain rowhead,elementype val,int row)
{
	Olchain NodetoRow = (Olnode *)malloc(sizeof(Olnode));
	NodetoRow->val = val;
	NodetoRow->row = row;
	NodetoRow->down = NULL;
	
	Olchain TempNode = rowhead;
	
	while(TempNode->down != NULL){
		
		if((TempNode->row < row) &&((TempNode->down->row > row)|(TempNode->down->row == row))){
			NodetoRow->down = TempNode->down;
			TempNode->down = NodetoRow;
		}
		else{
			TempNode = TempNode->down;
		}
	}
	if(TempNode->down == NULL){
		NodetoRow->down = TempNode->down;
			TempNode->down = NodetoRow;
	}
	printf("insert the row is succeed\n");
}

print函数:

void printNode(Crosschain * CrossChain)
{
	printColumn(CrossChain->colhead);
	printf("\n");
	printRow(CrossChain->rowhead);
	printf("\n");
}

void printColumn(Olchain colhead)
{
	Olchain TempNode = colhead;
	while(TempNode->right != NULL ){
		printf("(%d,%d)		",TempNode->column,TempNode->val);
		TempNode = TempNode->right;
	}
	if(TempNode->right == NULL){
		printf("(%d,%d)		",TempNode->column,TempNode->val);
	}
}


void printRow(Olchain rowhead)
{
	
	Olchain TempNode = rowhead;
	while(TempNode->down != NULL ){
		printf("(%d,%d)		",TempNode->row,TempNode->val);
		TempNode = TempNode->down;
	}
	if(TempNode->down == NULL){
		printf("(%d,%d)		",TempNode->row,TempNode->val);
	}  
}

删除数值函数:

void deleteNode(Crosschain * CrossChain,elementype val)
{
	deleteNodeColumn(CrossChain->colhead, val);
	deleteNodeRow(CrossChain->rowhead,val);
	
}

void deleteNodeColumn(Olchain colhead,elementype val)
{
	Olchain Tempchain = colhead;
	int STATUS = 0;
	
	//这个设计是非常好的,有两个暂时的,同个类型的struct 变量 
	while(Tempchain->right != NULL ){
		Olchain TempNode = Tempchain->right;
		if(TempNode->val == val){
			Tempchain->right = TempNode->right;
			
			free(TempNode);
			printf("delete %d in the column\n",val);
			printf("data  is 1\n");
			STATUS = 1;
		}
		else Tempchain = Tempchain->right; 
		printf("data  is 2\n");
	}
	if(Tempchain->val == val){
			Tempchain = NULL;
			free(Tempchain);
			printf("data  is 3\n");
			STATUS = 1;
			printf("delete %d in the column\n",val);
			printf("data  is 4\n");
	}
	if(STATUS == 0){
		printf("no such data\n");
	}
	
}


//delete这个一直是需要思考的地方,很高兴发现并修复了bug
// 1-设计是非常好的,有两个暂时的,同个类型的struct 变量
//2-while这里需要加if-else,else一定要加,不然会让if执行完再必然地执行下一句,等于跳了两次。有一个量没检测。
//更重要的是,有可能这么一跳,把 Tempchain自己跳到null了,会崩溃 
void deleteNodeRow(Olchain rowhead,elementype val)
{
	
	Olchain Tempchain = rowhead;
	int STATUS = 0;
	
	printf("data 1\n");
	
	//这个设计是非常好的,有两个暂时的,同个类型的struct 变量 
	while(Tempchain->down != NULL ){
		Olchain TempNode = Tempchain->down;
		
		printf("data 2\n");
		
		if(TempNode->val == val){
			Tempchain->down = TempNode->down;
			free(TempNode);
			STATUS = 1;
			printf("delete %d in the row\n",val);
		}
		else Tempchain = Tempchain->down; 
		printf("data 3\n");
	}
	if(Tempchain->val == val){
			//Tempchain->right = TempNode->right;
			printf("data 4\n");
			
			Tempchain = NULL;
			free(Tempchain);
			printf("delete %d in the row\n",val);
			
			printf("data 5\n");
			
			STATUS = 1;
	}
	if(STATUS == 0){
		printf("no such data\n");
	}	
}

destroy函数:

void destroyChain(Crosschain * CrossChain)
{
	destroyColumn(CrossChain->colhead);
	printf("destroy 1\n");
	destroyRow(CrossChain-> rowhead);
}

//很高兴,bug很清楚,这里不能删掉colhead和rowhead,否则就是没有头结点,会崩溃的,需要在main里删除 
void destroyColumn(Olchain colhead)
{
	while(colhead->right != NULL){
		Olchain TempNode = colhead->right;
		colhead->right = TempNode->right;
		free(TempNode);
	}
	printf("destroy column is finished\n");
}

void destroyRow(Olchain rowhead)
{
	while(rowhead->down != NULL){
		Olchain TempNode = rowhead->down;
		rowhead->down = TempNode->down;
		free(TempNode);
	}
	printf("destroy row is finished\n");
}

附上完整程序:

#include<stdio.h>
#include<malloc.h>

/*
功能分析:
这种十字链表结构,针对的对象是稀疏矩阵
所以不用全部显示和载入(这恰恰是麻烦的地方)
应该是插入的时候,做判断, 取出/删除时, 不做判断

函数:init(还是把它放在main里面)——print——insert——delete——destroy 

两个bug的发现和修复(逻辑的严密性太重要了)!!!! 

*/

typedef int elementype;
typedef struct Olnode{
	int row,column;
	elementype val;
	struct Olnode * right;
	struct Olnode *down;
}Olnode ,*Olchain;

typedef struct Crosschain{
	int rownum,colnum;
	struct Olink *rowhead, * colhead;
}Crosschain;

//void  insertNode(Olchain OLChain,elementype val,int row,int colum); 

void  insertNodeColumn(Olchain colhead,elementype val,int column); 
void  insertNodeRow(Olchain rowhead,elementype val,int row); 
void insertCrossChain(Crosschain * CrossChain,elementype val,int row,int column);

void printNode(Crosschain * CrossChain);
void printColumn(Olchain colhead);
void printRow(Olchain rowhead);


void deleteNode(Crosschain * CrossChain,elementype val);
void deleteNodeColumn(Olchain colhead,elementype val);
void deleteNodeRow(Olchain rowhead,elementype val);

void destroyChain(Crosschain * CrossChain);
void destroyColumn(Olchain colhead); 
void destroyRow(Olchain rowhead);





int main()
{	
	Olchain rowhead = (Olnode *)malloc(sizeof(Olnode));
	Olchain colhead = (Olnode *)malloc(sizeof(Olnode));
	
	rowhead->row = -1;
	rowhead->val = 0;
	rowhead->down = NULL;
	colhead->column = -1;
	colhead->val = -1;
	colhead->right = NULL;
	
	
	Crosschain * CrossChain = (Crosschain *)malloc(sizeof(Crosschain));
	CrossChain->rownum = 0;
	CrossChain->colnum = 0;
	CrossChain->rowhead = rowhead;
	CrossChain->colhead = colhead;
	
	
	insertCrossChain(CrossChain,23,3,2);
	
	printNode(CrossChain);
	
	insertCrossChain(CrossChain,34,4,3);
	printNode(CrossChain);
	
	
	//insertCrossChain(CrossChain,44,4,4);
	//printNode(CrossChain);
	
	deleteNode(CrossChain, 34);
	deleteNode(CrossChain, 35);
	
	destroyChain(CrossChain);
	
	return 0;
} 

void insertCrossChain(Crosschain * CrossChain,elementype val,int row,int column)
{
	insertNodeColumn(CrossChain->colhead,val,column);
	insertNodeRow(CrossChain->rowhead,val,row);
	printf("insert the  CrossChain is succeed\n");
	
} 


void  insertNodeColumn(Olchain colhead,elementype val,int column)
{
	Olchain NodetoColumn = (Olnode *)malloc(sizeof(Olnode));
	NodetoColumn->val = val;
	NodetoColumn->column = column;
	NodetoColumn->right = NULL;
	
	Olchain TempNode = colhead;
	
	while(TempNode->right != NULL){
		if((TempNode->column < column) &&((TempNode->right->column > column)|(TempNode->right->column == column))){
			NodetoColumn->right = TempNode->right;
			TempNode->right = NodetoColumn;
		}
		else{
			TempNode = TempNode->right;
		}
	}
	if(TempNode->right == NULL){
		NodetoColumn->right = TempNode->right;
			TempNode->right = NodetoColumn;
	}
	printf("insert the column is succeed\n");

}

void  insertNodeRow(Olchain rowhead,elementype val,int row)
{
	Olchain NodetoRow = (Olnode *)malloc(sizeof(Olnode));
	NodetoRow->val = val;
	NodetoRow->row = row;
	NodetoRow->down = NULL;
	
	Olchain TempNode = rowhead;
	
	while(TempNode->down != NULL){
		
		if((TempNode->row < row) &&((TempNode->down->row > row)|(TempNode->down->row == row))){
			NodetoRow->down = TempNode->down;
			TempNode->down = NodetoRow;
		}
		else{
			TempNode = TempNode->down;
		}
	}
	if(TempNode->down == NULL){
		NodetoRow->down = TempNode->down;
			TempNode->down = NodetoRow;
	}
	printf("insert the row is succeed\n");
}

void printNode(Crosschain * CrossChain)
{
	printColumn(CrossChain->colhead);
	printf("\n");
	printRow(CrossChain->rowhead);
	printf("\n");
}

void printColumn(Olchain colhead)
{
	Olchain TempNode = colhead;
	while(TempNode->right != NULL ){
		printf("(%d,%d)		",TempNode->column,TempNode->val);
		TempNode = TempNode->right;
	}
	if(TempNode->right == NULL){
		printf("(%d,%d)		",TempNode->column,TempNode->val);
	}
}


void printRow(Olchain rowhead)
{
	
	Olchain TempNode = rowhead;
	while(TempNode->down != NULL ){
		printf("(%d,%d)		",TempNode->row,TempNode->val);
		TempNode = TempNode->down;
	}
	if(TempNode->down == NULL){
		printf("(%d,%d)		",TempNode->row,TempNode->val);
	}
   
}

void deleteNode(Crosschain * CrossChain,elementype val)
{
	deleteNodeColumn(CrossChain->colhead, val);
	deleteNodeRow(CrossChain->rowhead,val);
	
}

void deleteNodeColumn(Olchain colhead,elementype val)
{
	Olchain Tempchain = colhead;
	int STATUS = 0;
	
	//这个设计是非常好的,有两个暂时的,同个类型的struct 变量 
	while(Tempchain->right != NULL ){
		Olchain TempNode = Tempchain->right;
		if(TempNode->val == val){
			Tempchain->right = TempNode->right;
			
			free(TempNode);
			printf("delete %d in the column\n",val);
			printf("data  is 1\n");
			STATUS = 1;
		}
		else Tempchain = Tempchain->right; 
		printf("data  is 2\n");
	}
	if(Tempchain->val == val){
			Tempchain = NULL;
			free(Tempchain);
			printf("data  is 3\n");
			STATUS = 1;
			printf("delete %d in the column\n",val);
			printf("data  is 4\n");
	}
	if(STATUS == 0){
		printf("no such data\n");
	}
	
}


//delete这个一直是需要思考的地方,很高兴发现并修复了bug
// 1-设计是非常好的,有两个暂时的,同个类型的struct 变量
//2-while这里需要加if-else,else一定要加,不然会让if执行完再必然地执行下一句,等于跳了两次。有一个量没检测。
//更重要的是,有可能这么一跳,把 Tempchain自己跳到null了,会崩溃 
void deleteNodeRow(Olchain rowhead,elementype val)
{
	
	Olchain Tempchain = rowhead;
	int STATUS = 0;
	
	printf("data 1\n");
	
	//这个设计是非常好的,有两个暂时的,同个类型的struct 变量 
	while(Tempchain->down != NULL ){
		Olchain TempNode = Tempchain->down;
		
		printf("data 2\n");
		
		if(TempNode->val == val){
			Tempchain->down = TempNode->down;
			free(TempNode);
			STATUS = 1;
			printf("delete %d in the row\n",val);
		}
		else Tempchain = Tempchain->down; 
		printf("data 3\n");
	}
	if(Tempchain->val == val){
			//Tempchain->right = TempNode->right;
			printf("data 4\n");
			
			Tempchain = NULL;
			free(Tempchain);
			printf("delete %d in the row\n",val);
			
			printf("data 5\n");
			
			STATUS = 1;
	}
	if(STATUS == 0){
		printf("no such data\n");
	}
	
}

void destroyChain(Crosschain * CrossChain)
{
	destroyColumn(CrossChain->colhead);
	printf("destroy 1\n");
	destroyRow(CrossChain-> rowhead);
}

//很高兴,bug很清楚,这里不能删掉colhead和rowhead,否则就是没有头结点,会崩溃的,需要在main里删除 
void destroyColumn(Olchain colhead)
{
	while(colhead->right != NULL){
		Olchain TempNode = colhead->right;
		colhead->right = TempNode->right;
		free(TempNode);
	}
	printf("destroy column is finished\n");
}

void destroyRow(Olchain rowhead)
{
	while(rowhead->down != NULL){
		Olchain TempNode = rowhead->down;
		rowhead->down = TempNode->down;
		free(TempNode);
	}
	printf("destroy row is finished\n");
}

效果:
数据结构(六)——数组

相关文章:

  • 2021-09-14
  • 2021-10-20
  • 2021-10-19
  • 2021-06-04
  • 2022-01-11
  • 2021-07-26
猜你喜欢
  • 2021-10-26
  • 2021-06-03
  • 2021-04-23
  • 2022-02-25
  • 2022-12-23
  • 2022-12-23
  • 2021-10-12
相关资源
相似解决方案