1. 程式人生 > 其它 >矩陣原地轉置演算法C++實現

矩陣原地轉置演算法C++實現

技術標籤:演算法c++演算法矩陣

普林斯頓演算法第四版1.1.13題目解決方案

矩陣轉置是線性代數中非常基礎的操作,如果從新開闢新的空間將原矩陣的資料對映到新矩陣,演算法雖然非常簡單,但是卻浪費大量空間,尤其對於矩陣規模比較大的情況。本文使用一種矩陣原地轉置演算法,保證矩陣主題不會消耗額外空間,但是使用了flag陣列來標識矩陣元素的轉移情況

核心程式碼為如下函式

void TransposeTwoArray(int* IndataPtr, size_t width, size_t height)
{
	//計算flag陣列的總容量
	size_t n = width * height;

	//flag陣列,與原來矩陣陣列的元素對應,如果為false表明該元素未被轉移過,如果未       true,這表示該元素被轉移過,原有遍歷終止,開始新的遍歷轉移
bool* flagPtrIn = new bool[width * height]{}; //指示當前遍歷起始位置索引,從陣列第一個元素開始,一直遍歷到末尾結束 size_t currentIndex = 0; for (int i = 0; i < height; i++) { for (int j = 0; j < width; j++) { //內部迴圈遍歷的起始索引,如果遍歷連續,則內部迴圈,並自動計算下一個替代位置的索引 int Ini = i; int Inj = j; size_t srcIndex = Ini * width +
Inj; size_t dstIndex = Inj * height + Ini; //被替代的位置的元素,需要提前取出,並且用於替換新的目的地址的元素,成為新的原地址元素 int preValue= IndataPtr[srcIndex]; //當從一個元素位置開始轉移替換,檢查要被替換的位置是否被遍歷過,如果被替換過,則替換內迴圈,開始去新的位置迭代,如果目的位置未被替代過,將其flag改為true,並進去替代,知道完整一個閉環 while (flagPtrIn[dstIndex] == false && currentIndex <
width * height) { flagPtrIn[dstIndex] = true; int tmp = IndataPtr[dstIndex]; IndataPtr[dstIndex] = preValue; //根據新矩陣一維陣列的索引反算出原矩陣索引位置 Ini = dstIndex / width; Inj = dstIndex % width; srcIndex = Ini * width + Inj; dstIndex = Inj * height + Ini; preValue = tmp; } currentIndex++; } } }

函式引數為:
int* IndataPt------陣列的首地址
size_t width-------矩陣寬度
size_t height------矩陣高度

測試函式

/*int dataArray[3][4]= { 1,2,3,4,5,6,7,8,9,10,11,12 };*/

	int dataArray[3][1] = { 1,2,3 };

	const int oldWidth = 3;
	const int oldHeight = 1;
	const int newWidth = 1;
	const int newHeight = 3;

	//列印原來陣列
	for (int i = 0; i < oldHeight; i++)
	{
		for (int j = 0; j < oldWidth; j++)
			cout << "   " << dataArray[i][j];
		cout << endl;
	}

	TransposeTwoArray((int*)dataArray, oldWidth, oldHeight);

	for (int i = 0; i < newHeight; i++)
	{
		for (int j = 0; j < newWidth; j++)
			cout << "   " << *((int*)dataArray + i * newWidth + j);
		cout << endl;
	}

測試結果
在這裡插入圖片描述