十字链表 Orthogonal List

来源:互联网 发布:手机电信网络加速器 编辑:程序博客网 时间:2024/04/30 15:24

十字链表,用于存储 稀疏矩阵 或 有向图。

在实现非二元LDPC码译码过程中,需要用十字链表存储校验矩阵H。

网上找到 博客 http://blog.csdn.net/zhuyi2654715/article/details/6729783 讲解的十分清晰

上图可以 清晰地展现十字链表的数据结构 : 整个十字链表的头指针指向横向和纵向的头指针数组,再由每个对应行和列上的头指针作为链表头,指向各个稀疏节点。

#include <stdio.h>#include <malloc.h>typedef struct olnode{int i;//表示矩阵的行号int j;//表示矩阵的列号int value;//或者值的类型设为element_typestruct olnode *right;//横向下一个节点的地址struct olnode *down; //纵向下一个节点的地址}olnode,*olist;typedef struct crosslist{olist *rhead,*chead;int rownum;//矩阵行数int colnum;//矩阵列数int elenum;//矩阵非零元素数}crosslist;void creatOList(crosslist *H);void display(crosslist *H);void creatOList(crosslist *H){FILE *fp;fp = fopen("Orthogonal_List_matrix.txt","r");int i,j;int m,n,ele;//不要直接把数据读入数据结构中,设置中间值,进行检测,确定后拷贝到数据结构中olnode *p,*q;int flag;//建立稀疏矩阵,且用十字链表存储if (H->rhead)//如果原先存在,销毁{//destroy();}do{flag = 1;//printf("输入需要创建的矩阵的行数、列数以及非零元的个数\n");fscanf(fp,"%d%d%d",&m,&n,&ele);if (m<0||n<0||ele<0||ele>m*n){flag = 0;}}while (!flag);H->rownum = m;H->colnum = n;H->elenum = ele;//创建横向和纵向的 头指针数组 ,并初始化H->rhead = (olist*)malloc(sizeof(olist)*(H->rownum+1));//H->chead = (olnode*)malloc(sizeof(olnode)*(H->colnum+1));H->chead = (olist*)malloc(sizeof(olist)*(H->colnum+1));if (!H->rhead||!H->chead){exit(-1);}for (i = 1;i<H->rownum+1 ;i++ ){H->rhead[i] = NULL;}for (i = 1;i<H->colnum+1 ;i++ ){H->chead[i] = NULL;}//输入节点并插入表中i = 1;while (i<=H->elenum){do{flag = 1;//printf("输入第%d个结点行号、列号以及值",i);//scanf("%d%d%d",&m,&n,&ele);fscanf(fp,"%d%d%d",&m,&n,&ele);if (m<0||n<0){flag = 0;}elsei++;}while (!flag);p = (olnode*)malloc(sizeof(olnode));//建立新节点并存入数据if (!p){exit(-1);}p->i = m;p->j = n;p->value = ele;//将节点插入/*插入的两种情况:1.这一行中没有节点=>直接插入2.这一行中有节点=>找到正确位置插入*///行if (H->rhead[m] == NULL || H->rhead[m]->j > n)//一行为空或者为一行中下标最小的...试试把插入合在一起{p->right = H->rhead[m];//插入在第一个节点H->rhead[m] = p;//头指针指向第一个节点}else{//在一行中从头寻找插入位置for (q = H->rhead[m]; q->right && q->right->j < n ;q = q->right );p->right = q->right;q->right = p;}//列if (H->chead[n] == NULL || H->chead[n]->j > m){p->down = H->chead[n];H->chead[n] = p;}else{for (q = H->chead[n];q->down && q->down->i < m ;q = q->down );p->down = q->down;q->down = p;}}}void display(crosslist *H){int i;olnode *p;for (i = 1;i<=H->rownum ;i++ ){p = H->rhead[i];while (p){printf("(%d,%d)=%d\n",p->i,p->j,p->value);p = p->right;}}}int main(){crosslist *H;H = (crosslist*)malloc(sizeof(crosslist));creatOList(H);display(H);return 0;}

实现时,由于读取校验矩阵H时需要链表是双向的,才能进行双向读取,所有每个节点需要再加入两个指针,如下:

typedef struct pnode{int value;//a = 0 ~ q-1int col;int row;pnode *right,*left,*up,*down;//double *pmn;}pnode,*plist;typedef struct crosslist{plist* right;plist* down;}crosslist;



0 0
原创粉丝点击