十字链表

Posted 鹏达君

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了十字链表相关的知识,希望对你有一定的参考价值。

文字描述

 

1、十字链表的结点的结构

技术分享
down 和right分别指向该列和该行的下一个元素,
 
Data保存的是该非零元素的信息(包括,以及存储的元素值
 
 
 

2、十字链表的存储

 
 
技术分享
分别有记录指向该行和该列的第一个非零元素的头指针数组OLNode[] rhead 和OLNode[] chead
 
 
 
 
 
 
 

代码实现

 
 
 

1、稀疏矩阵的十字链表存储的结点结构

package org.Stone6762.entity; 

/** 
* @author_Stone6762 
*/ 
public class OLNode { 

private TripleNode data;// 三元组存储的数据包括该元素所在的行列和数值 
private OLNode Right;// 行链表指针 
private OLNode down;// 列链表指针 

/** 
* @构造器  
* @Description: TODO() 
*/ 
public OLNode() { 
this(null, null, null); 


/** 
* @构造器  
* @Description: TODO() 
* @param data 
*/ 
public OLNode(TripleNode data) { 
this(data, null, null); 


public OLNode(TripleNode data, OLNode right, OLNode down) { 
super(); 
this.data = data; 
Right = right; 
this.down = down; 


public TripleNode getData() { 
return data; 


public OLNode getRight() { 
return Right; 


public void setRight(OLNode right) { 
Right = right; 


public OLNode getDown() { 
return down; 


public void setDown(OLNode down) { 
this.down = down; 


public void setData(TripleNode data) { 
this.data = data; 


}

2、稀疏矩阵十字链表存储法

package org.Stone6762.Array.SparseArray; 

import org.Stone6762.Utils.ArrayUtils; 
import org.Stone6762.entity.OLNode; 
import org.Stone6762.entity.TripleNode; 

/** 
* @author_Stone6762 
*/ 
public class CrossList { 

/** 
* @cols原始矩阵的列数 
*/ 
private int cols; 
/** 
* @rows原始矩阵的行数 
*/ 
private int rows; 
/** 
* @nums原始矩阵中非零元素的个数 
*/ 
private int nums; 
/** 
* @rhead列指针----单纯的充当头指针,执行该行第一个非零元素,所以其长度等于cols 
*/ 
private OLNode[] rhead; 
/** 
* @chead行指针----单纯的充当头指针,执行该列第一个非零元素,其长度等于rows 
*/ 
private OLNode[] chead; 

public CrossList(int cols, int rows) { 
inintHeader(cols, rows); 


/** 
* @构造器  
* @Description: TODO(将一个数组变成一个稀疏矩阵存储的形式) 
* @param datas 
*/ 
public CrossList(double[][] datas) { 
inintHeader(datas[0].length, datas.length); 
for (int row = 0; row < datas.length; row++) { 
for (int col = 0; col < datas[0].length; col++) { 
if (datas[row][col] != 0) { 
insert(row, col, datas[row][col]); 





/** 
* @Description: TODO( 在该稀疏矩阵中插入一个元素 ) 
* @param row 
* @param col 
* @param data 
*/ 
public void insert(int row, int col, double data) { 
this.nums++; 
// 创建一个十字链表结点,并将数据存储进去 
TripleNode da = new TripleNode(row, col, data); 
OLNode newNode = new OLNode(da); 

// 通过行列头指针,确定指向该新结点的指针 
OLNode t = rhead[row];// 找到该行的头指针 
while (t.getRight() != null) {// 找到该行的末尾 
t = t.getRight(); 

t.setRight(newNode);// 让该行的末尾指向该新结点 
// 
t = chead[col]; 
while (t.getDown() != null) { 
t = t.getDown(); 

t.setDown(newNode); 


/** 
* @Description: TODO( 通过行数和列数,初始化行列头指针 ) 
* @param cols列 
* @param rows行 
*/ 
public void inintHeader(int cols, int rows) { 
this.cols = cols; 
this.rows = rows; 
rhead = new OLNode[cols]; 
chead = new OLNode[rows]; 
// 初始化行的头指针 
for (int i = 0; i < rhead.length; i++) { 
rhead[i] = new OLNode(); 

// 设置列的头指针 
for (int i = 0; i < chead.length; i++) { 
chead[i] = new OLNode(); 



/** 
* @Description: TODO( 将十字存储的链表还原成原始矩阵 ) 
* @return 
*/ 
public double[][] reBackToArr() { 
double arr[][] = new double[rows][cols]; 
for (int i = 0; i < rhead.length; i++) { 
OLNode t = rhead[i]; 
while (t != null) { 
if (t.getData() != null) {// 头指针数据为空 
arr[t.getData().getRow()][t.getData().getColumn()] = t 
.getData().getValue(); 

t = t.getRight(); 



return arr; 


/** 
* @Description: TODO( 遍历整个十字链表 ) 
*/ 
public void printfArrOfRC() { 
System.out.println("原始矩阵 共" + rows + "行, " + cols + "列, " + this.nums 
+ "个非零元素"); 
System.out.println("---------------------------------------"); 
System.out.println("从行上来看"); 
System.out.println("行号"); 
for (int i = 0; i < rhead.length; i++) { 
System.out.print(i + " "); 
OLNode t = rhead[i]; 
while (t != null) { 
if (t.getData() != null) {// 头指针数据为空 
System.out.print(t.getData().getValue() + "->"); 

t = t.getRight(); 

System.out.println(); 

System.out.println("---------------------------------------"); 
System.out.println("从列上来看"); 
System.out.println("列号"); 
for (int i = 0; i < chead.length; i++) { 
System.out.print(i + " "); 
OLNode t = chead[i]; 
while (t != null) { 
if (t.getData() != null) { 
System.out.print(t.getData().getValue() + "->"); 

t = t.getDown(); 

System.out.println(); 



/** 
* @Description: TODO( 以数组的形式打印) 
*/ 
public void printfArr() { 
System.out.println("稀疏矩阵的三元组储存结构为: "); 
System.out.println("行数" + rows + ", 列数为:" + cols + " ,非零元素个数为: " 
+ nums); 
double arr[][] = reBackToArr(); 
ArrayUtils.printMulArray(arr); 


public CrossList() { 
super(); 


public CrossList(int cols, int rows, int nums, OLNode[] rhead, 
OLNode[] chead) { 
super(); 
this.cols = cols; 
this.rows = rows; 
this.nums = nums; 
this.rhead = rhead; 
this.chead = chead; 


public int getCols() { 
return cols; 


public void setCols(int cols) { 
this.cols = cols; 


public int getRows() { 
return rows; 


public void setRows(int rows) { 
this.rows = rows; 


public int getNums() { 
return nums; 


public void setNums(int nums) { 
this.nums = nums; 


public OLNode[] getRhead() { 
return rhead; 


public void setRhead(OLNode[] rhead) { 
this.rhead = rhead; 


public OLNode[] getChead() { 
return chead; 


public void setChead(OLNode[] chead) { 
this.chead = chead; 


public static void main(String[] args) { 
double[][] arr = { { 0, 0, 1, 0 }, { 1, 0, 0, 4 }, { 0, 0, 3, 0 }, 
{ 1, 2, 0, 4 } }; 
CrossList cList = new CrossList(arr); 
cList.printfArrOfRC(); 



}

 































































































































































































































































































以上是关于十字链表的主要内容,如果未能解决你的问题,请参考以下文章

算法链表链表相关问题总结

有向图的十字链表存储形式

数据结构-链表链表的基本操作

数据结构-链表链表的相关算法

[11道链表经典笔试题]优化的算法思想:反转链表链表相交快慢指针

reorder-list——链表快慢指针逆转链表链表合并