重新複習資料結構,十字鏈表主要在兩個地方應用:疏鬆陣列的儲存, 有向圖的儲存。
疏鬆陣列,常用三元組儲存,但是當矩陣的非零元素和位置在操作過程中變化較大時,就不一採用順序結構儲存了,此時十字鏈表就是不錯的選擇。
下面是十字鏈表的資料結構,以及建立函數,篇幅有限沒有帖記憶體釋放的函數:
typedef struct QLNode
...{
int iPos, jPos; //非零元素的行列下標;
int iElem; //元素;
struct QLNode *right, *down;
}QLNode;
typedef struct QLNode* QLink;
typedef struct
...{
QLink *rHead, *cHead; //行列的頭指標;
int RowNum, ColNum, TotalNum;
}CrossList;
bool CreatCrossList(CrossList& CroLit)
...{
int row, coll, total;
cin>>row>>coll>>total;
CroLit.RowNum=row; CroLit.ColNum=coll; CroLit.TotalNum=total;
CroLit.rHead= new QLink[row]; //建立行頭指標表;
CroLit.cHead= new QLink[coll]; //建立列頭指標表;
//初始化頭指標表;
for (int i=0; i<row; i++)
CroLit.rHead[i]=NULL;
for (int i=0; i<coll; i++)
CroLit.cHead[i]=NULL;
int i, j, elem; //以三元組的形式輸入
for(cin>>i>>j>>elem; elem!=0; cin>>i>>j>>elem)
...{
QLink pTem= new QLNode;
pTem->right=pTem->down=NULL;
pTem->iPos=i; pTem->jPos=j; pTem->iElem=elem;
//直接插入:空,或者列座標大於此行鏈表中的最大列座標
// 同一行裡面,鏈表按照列的座標排序,
if( CroLit.rHead[i]==NULL || CroLit.rHead[i]->jPos>j )
...{
pTem->right= CroLit.rHead[i];
CroLit.rHead[i]=pTem;
}
else //查尋在行表中的插入位置:
...{
QLink bg;
for(bg=CroLit.rHead[i]; bg->right && bg->right->jPos<j; bg=bg->right);
pTem->right=bg->right; bg->right=pTem;
} //完成行插入。
//直接插入:空,或者行座標大於此列鏈表中的最大行座標
// 同一列裡面,鏈表按照行的座標排序,
if( CroLit.cHead[j]==NULL || CroLit.cHead[j]->iPos>i )
...{
pTem->down= CroLit.cHead[j];
CroLit.cHead[j]=pTem;
}
else //查尋在列表中的插入位置:
...{
QLink bg;
for(bg=CroLit.cHead[j]; bg->down && bg->down->iPos<i; bg=bg->down);
pTem->down=bg->down; bg->down=pTem;
} //完成列插入。
}
return true;
}
//輸出各行元素
void DisplayRow(CrossList dest)
...{
for (int i=0; i<dest.RowNum; i++)
...{
QLink tem=dest.rHead[i];
while (tem)
...{
cout<<"( "<<tem->iPos<<", ";
cout<<tem->jPos<<", ";
cout<<tem->iElem<<" )";
tem=tem->right;
}
cout<<endl;
}
}
舉個例子,疏鬆陣列:
| 3 0 0 5 |
| 0 2 0 0 |
| 2 0 0 0 |
/*測試輸入:
3 4 4
0 0 3
0 3 5
1 1 2
2 0 2
0 0 0 /表示結束*/
/*測試輸出:
( 0, 0, 3 )( 0, 3, 5 )
( 1, 1, 2 )
( 2, 0, 2 )
請按任意鍵繼續. . .*/
下面是該十字鏈表的儲存圖: