1. 程式人生 > >稀疏矩陣的十字連結串列實現:行列連結串列

稀疏矩陣的十字連結串列實現:行列連結串列

<span style="font-size:12px;">//將current插入到其對應的行連結串列的合適位置,使行連結串列的元素按行號遞增順序排列				
void Insert_R( OLNode *rhead, OLNode * current )
{
	if( ( rhead + current->row )->right == NULL ){
		( rhead + current->row )->right = current;
	}
	else{	    //將當前項插入到對應行連結串列的第一項,並對其進行排序
		current->right = ( rhead + current->row )->right;
		( rhead + current->row )->right = current;
		Increse_row( rhead + current->row );	
	}
}

//將current插入到其對應的列連結串列的合適位置,使列連結串列的元素按列號遞增順序排列
void Insert_C( OLNode *chead, OLNode * current )
{
	if( ( chead + current->col )->down == NULL ){
		( chead + current->col )->down = current;
	}
	else{	    //將當前項插入到對應行連結串列的第一項,並對其進行排序
		current->down = ( chead + current->col )->down;
		( chead + current->col )->down = current;
		Increse_col( chead + current->col );	
	}
}</span>
3、建立稀疏矩陣時我們同樣需要矩陣的引數:詳見稀疏矩陣的順序儲存結構表示
//建立稀疏矩陣,矩陣元素從第一行第一列開始沒有第0行和第0列,矩陣的對應值的行列值即為實際的行列值
void CreateSMatrix_OL( CrossList *matrix )
{
	int i;
	OLNode *current;

	printf( "please input the total rows of the matrix:\n" );   //輸入矩陣的總行數
	scanf( "%d", &matrix->row_num ); 
	printf( "please input the total colums of the matrix:\n" );//輸入矩陣的總列數
	scanf( "%d", &matrix->col_num ); 
	printf( "please input the total numbers of non_zero elements of the matrix:\n" );  //輸入矩陣的非零值的個數
	scanf( "%d", &matrix->non_zero );
	if( matrix->non_zero > matrix->row_num * matrix->col_num ){   //輸入的非零值個數太多報錯並結束程式的執行
		printf( "CreateSMatrix Error:too much none zero elements\n" );
		exit( EXIT_FAILURE );
	}

	if( !Malloclist( matrix ) ){							 //為matrix分配空間,若分配失敗報錯並結束執行
		printf( "CreateSMatrix_OL Error:OVERFLOW!\n" );
		exit( EXIT_FAILURE );
	}

	printf( "make sure: 0<row<=%d, 0<col<=%d\n", matrix->row_num, matrix->col_num ); 
	for( i = 0; i < matrix->non_zero; i++ ){				//分配儲存空間成功,以(行,列,值)的形式逐個輸入矩陣的值
		current = ( OLNode * )malloc( sizeof( OLNode ) ); //為一個矩陣項分配空間
		if( !current ){									 //分配儲存空間失敗,報錯並結束程式執行
			printf( "CreateSMatrix Error: OVERFLOW\n" );
			exit( EXIT_FAILURE );
		}
		current->down = NULL;							//將current的down和right都初始化為NULL
		current->right = NULL;
		printf( "please input the (row, colum, value) of the %d none zero element of the matrix:\n", i + 1 ); 
		scanf( "%d,%d,%d", ¤t->row, ¤t->col, ¤t->value );
		if( current->row <= 0 || current->row > matrix->row_num || current->col > matrix->col_num || current->col <= 0 ){ //當輸入的行列值不滿足條件時
			printf( "CreateSMatrix Error:wrong input of row or col\n" );   //列印錯誤並結束程式執行
			exit( EXIT_FAILURE );
		}
		//將current插入到對應的行列連結串列的合適的位置
		Insert_R( matrix->rhead, current );
		Insert_C( matrix->chead, current );	
	}	
}

4、進行矩陣乘法時,由於即有行連結串列,又有列連結串列,我們可以很方便的對行列進行操作。用第一個矩陣的第i個行連結串列與第二矩陣的各列連結串列分別進行運算。不需要遍歷第二個矩陣的所有項。只需要按照連結串列進行判斷和運算。
<pre name="code" class="cpp">//當第一個矩陣的列值等於第二個矩陣的行值時,對這兩個矩陣進行相乘的運算並將結果存在result矩陣中
void MultSMatrix_OL( CrossList *matrix1, CrossList *matrix2, CrossList *result )
{	
	int i;
	int j;
	int count;
	OLNode *current1;
	OLNode *current2;
	OLNode *current;

	if( matrix1->col_num != matrix2->row_num ){  //如果兩個矩陣的行數或者列數不相同
		printf( "AddSMatrix Error: the colum of the first matrix and therow of the second matrix is different!\n" );
	}
	else{   
		result->row_num = matrix1->row_num;
		result->col_num = matrix2->col_num;
	
		if( !Malloclist( result ) ){//為結果矩陣分配記憶體空間
			printf( "CopySMatrix_OL Error:OVERFLOW!\n" );
			exit( EXIT_FAILURE );
		}

		i = 1;
		count = 0;
		while( i <= matrix1->row_num ){ //對第一個矩陣逐行進行運算
			j = 1;
			while( j <= matrix2->col_num ){  //用第一個矩陣的第i個行連結串列的各項依次與第二個矩陣的各個列連結串列的各項進行合適的運算
				current1 = ( matrix1->rhead + i )->right;
				current2 = ( matrix2->chead + j )->down;
				current = ( OLNode * )malloc( sizeof( OLNode ) ); //為一個矩陣項分配空間
				if( !current ){  //分配儲存空間失敗,報錯並結束程式執行
					printf( "SubSMatrix_OL Error: OVERFLOW\n" );
					exit( EXIT_FAILURE );
				}
				else{             //分配儲存空間成功呢,初始化
					current->value = 0;  
					current->right = NULL;
					current->down = NULL;
				}
				while( current1 && current2 ){  //當第一個矩陣的第i個行連結串列和第二個矩陣的第j個列連結串列均沒有到達末尾時
					if( current1->col == current2->row ) {   //如果current1的列號與current2的行號相等
						current->row = current1->row;  //current1的行號和current2的列號構成結果矩陣項current的行列號
						current->col = current2->col;
						current->value += current1->value * current2->value;//current1和current2相乘的結果作為current的value值
						current1 =current1->right;//繼續下一項運算
						current2 = current2->down;
					}
					else if( current1->col < current2->row  )  //如果current1的列號小於current2的行號
						current1 =current1->right;     //取current1的下一項進行比較運算
					else								//如果current1的列號大於current2的行號
						current2 = current2->down;		//取current2的下一項進行比較運算
				}
				if( current->value == 0 ){  //如果current的value的最終結果為0,說明第一個矩陣的第i行中的所有元素的列號都與
					free( current );		//第二個矩陣的第j列中的所有元算的行號都不想等,即沒有滿足相乘條件的項,釋放current
				}
				else{                 //如果current的value的最終結果不為0,則將current插入到結果矩陣的合適位置
					Insert_R( result->rhead, current );
					Insert_C( result->chead, current );
					count++;  ////每插入到結果矩陣中一個矩陣項,count就增加1,用於統計結果矩陣的非零值的個數
				}
				j++;
			}
			i++;
		}
		result->non_zero = count;
	}
}