理论基础
串
串的存储方式 :
定长存储方式 : 用一维数组存储, 后边加 ' \0 ' . \0 表示终结
堆分配存储 : typedef struct {
char * ch ;
int length ;
} HString ;
堆分配方式更灵活.
串的块链式存储表示 : 没有另外两种存储方法灵活 ( 定长存储 , 堆分配 ).
KMP 算法 ( 模式匹配 )
串的模式匹配是指,指定主串,子串。找到主串中子串的匹配情况。Index( S,T,pos ) , 其中pos指在主串中开始匹配的位置。
普通的匹配算法是由主串和模式串中的字符依次递增比对。当出现不同时,从主串的刚刚比对的第一个位置+1,再进行匹配。
这样就有个问题,当主串是 '0000000000000000000001' , 模式串是 '00000001' ,此时,每次都是比对了很多次之后发现不匹配,再 主串指针向后一位,
仍然要移动很多次后,才发现不匹配。每次都是到模式串的最后一位。效率很低。
串动态分配常用操作 : 如下 :
/* The basic operate , string
** Author : Kevin
** Date : 2012/02/28
*/
#include"stdio.h"
#include"alloc.h"
#include"stdlib.h"
/*堆存储方式*/
typedef struct{
char *ch; /*assign memory*/
int length ;
}HString ;
/*创建字符串*/
int StrAssign( HString *t, char *chars ){
int i ;
char *c;
for(i=0,c=chars; *c!='\0'; ++i,++c); /*求字符串的长度,即 i 值*/
t->ch = (char*)malloc(i*sizeof(char));
t->length = i;
c = chars;
for(i=0; i<t->length; i++){
/*t.ch[i] = c[i];*/
*(t->ch+i) = *(c+i); /* 这种方式和以上的注释的方式都可以*/
printf("%c",t->ch[i]);
}
return 1;
}
/*返回字符串长度*/
int StrLength( HString t ){
return t.length ;
}
/*比较两个字符串*/
int StrCompare(HString t, HString s){
int i=0;
while(i<t.length && i<s.length){
if(t.ch[i]==s.ch[i]){
}else if(t.ch[i]<s.ch[i]){
return -1;
}else{
return 1;
}
i++;
}
if(t.length == s.length){
return 0;
}else if(t.length < s.length){
return -1;
}else{
return 1;
}
}
/*清空字符串,类似初始化*/
int ClearString(HString *t){
int i ;
for(i=0; i<t->length; i++){
*(t->ch+i) = '';
}
return 1;
}
/*连接两个字符穿*/
int Concat(HString *t, HString s1, HString s2){
int i ;
int length ;
int j ;
length = s1.length + s2.length ;
t->ch = (char*)malloc(length*sizeof(char));
for(i=0; i<s1.length; i++)
*(t->ch+i) = *(s1.ch+i);
for(i=s1.length,j=0;i<s2.length+s1.length; i++,j++)
*(t->ch+i) = *(s2.ch+j);
t->length = s1.length + s2.length ;
return 1;
}
/*求子串*/
int SubString(HString t, HString *s, int pos, int len){
int i ;
s->ch = (char*)malloc(len*sizeof(char));
for(i=0; i<len; i++){
*(s->ch+i) = *(t.ch+pos+i);
}
s->length = len;
return 1;
}
/*复制字符串*/
int StrCopy(HString t, HString *s){
int i;
s->ch = (char*)malloc(t.length*sizeof(char));
for(i=0; i<t.length; i++)
*(s->ch+i) = *(t.ch+i);
s->length = t.length;
return 1;
}
/*指定位置插入字符串*/
int StrInsert(HString *t, int pos, HString s){
int i,j ;
t->ch = (char*)realloc(t->ch,(t->length+s.length)*sizeof(char));
for(i=t->length-1; i>=pos; i--){
*(t->ch+(s.length+i)) = *(t->ch+i);
}
for(j=0; j<s.length; i++,j++){
*(t->ch+pos+j) = *(s.ch+j);
}
t->length = t->length+s.length;
return 1;
}
/*指定位置删除字符串,指定删除长度问题*/
int StrDelete(HString *t, int pos, int len){
int i = 0;
int length = t->length - len ;
for(i=pos; i<t->length-len; i++){
*(t->ch+i) = *(t->ch+i+len);
printf("%d",i);
}
t->length = t->length-len;
}
/*销毁字符串*/
void StrDestory(HString *t){
free(t);
}
KMP 算法:
/* 初始化NEXT函数 */
void InitNext(HString s, int *pn){
int i, j;
pn[1] = 0; /*NEXT[0] = 0 , pn[0] ¼´ NEXT[0]²»´æÔÚ*/
pn[2] = 1; /*NEXT[1] = 1*/
for(i=2; i<=s.length; i++){
j = i ;
do{
if(*(s.ch+(i-1)) == *(s.ch+(pn[j]-1))) {
pn[i+1] = pn[j]+1;
break ;
}
else{
j = pn[j];
}
}while(j != 1);
if(j == 1){
pn[i+1] = 1;
}
}
}
/*求 NEXT 值*/
int Nextj(int *p, int j){
return *(p+j);
}
/* KMP 算法*/
int KmpString(HString *ps, HString *pm , int pos , int *p){
int i;
int j;
i = pos;
j = 1;
while(i<ps->length && j< pm->length){
if(*(ps->ch+i) == *(pm->ch+j) || j==0){
i++;
j++;
}
else{
j = Nextj(p , j);
}
}
if(j>=pm->length)
return i-pm->length;
else
return 0;
}
int main()
{
char *c = "abaabaf";
char *mc = "abcdababcddabaabafaass";
int next[7];
int i ;
int kmp_status ;
int sta, stb ;
HString smodel,smain ;
sta = StrAssign(&smodel,c);
stb = StrAssign(&smain,mc);
if(sta){
printf("model is assigned \n");
printf("The model length %d\n",smodel.length);
}else{
printf("model assign error\n");
return 0;
}
if(stb){
printf("main string is assigned \n");
printf("The String length %d\n",smain.length);
}else{
printf("main string assign error\n");
return 0;
}
InitNext(smodel,next);
/*
for(i=0;i<=7;i++)
printf("%d,",next[i]);
*/
printf("\n");
kmp_status = KmpString(&smain, &smodel, 1, next);
if(kmp_status)
printf("It is ok , The Location is %d",kmp_status);
else
printf("This is not matched , sorry ^_^");
getchar();
}
数组
typedef ElemType Array2[ m ][ n ] 等价于
typedef ElemType Array1[ n ] ;
typedef Array1 Array2[ n ] ;
将数组的定义拆开 , 定义2维数组时 , 可以如上想象 , 同理类推 :
数组使用顺序存储 ( 内存分配一整块空间 )
矩阵的压缩存储 : 为多个值相同的元只分配一个存储空间,对零元不分配存储空间。(一般可以使用全部存储,全部存储,运算方便)
存储三元表 :( 1,2,12) 横坐标,纵坐标,值
三元组存储的具体物理实现:
1。三元组顺序表
typedef struct {
int i , j ; //坐标
ElemType e ;
} Triple ;
typedef struct {
Triple data[MAXSIZE+1]; //存储实际非0元等等
int mu,nu,tu; //矩阵真正的行列数(包括0元),非0元个数
} TSMatrix ;
非0元顺序存储是以行顺序为主序排列。便于计算,但是,若需按行号存取某一行的非零元,则需从头开始查找。 -->必须是行,不是随便存储的
2。行逻辑链接顺序表 ( 也是行顺序存储的 , 只是加了一个知道每行第一个非0元的位置 )
为了便于随机存取任意一行的非零元。则需知道每一行的第一个元素再三元组(数组)中的位置。
typedef struct {
Triple data[MAXSIZE+1]; //记录数据和坐标
int rpos[MAXRC+1] ; //记录各行第一个非0元的位置,注意此位置是指在 data数组中的序号,而不是此行的列
int mu , nu , tu ; //矩阵的行数,列数,非0元个数
}RLSMatrix ;
这样,如果想找某一行的第1个非0元,可以查到该 rpos值,找到对应的 data 数组中该值,就找到了该结构体,也就找到了 i, j
3。十字链表
当矩阵的非0元个数和位置在操作过程中变化较大时。例如 a= a+b
以上图不是很清楚,应该是在上边和左侧各有个指针数组,chead , rhead 这是两个指针数组
这里的行指针和列指针并不是单一的一个,而是一组,多个。
typedef struct OLNode{t
int i , j ; //坐标O
ElemType e ; //值
struct OLNode *right , *down ; //行,列指针
}OLNode, *OLink;
typedef struct {
OLink *rhead , *chead ; //行和列链表头指针向量基址由 createSMatrix 创建
int mu , nu , tu ;
} CrossList ;
注意此处的 OLink * rhead *chead ; 此处是OLink本来就是定义指针变量的,所以此处为二级指针,即rhead , chead 指向一个指针,此指针指向OLink类型的指针。
而且如上图,由于十字链表的行列指针并不是一个,而是一组。所以此两个指针。rhead , chead 正式指向行的一组和列的一组的首地址。
而 CreateSMatrix中会根据实际数组的行列数而动态分配此行列组指针
M.rhead = (OLink *) malloc ((mu+1)*sizeof(OLink)) ;
M.chead = (OLink*) malloc((nu+1)* sizeof(OLink));
注意:此处的确给每行每列都分配了指针,并且注意sizeof(OLink),为什么要用OLink,因为分配的内存是为了存放指向OLink类型的指针。其实就相当于分配了
两个指针数组,数组中的指针是指向OLink类型。
广义表
定义 : LS = ( α1,α2,α3...,αn)
其中 α1...αn 即可以是单个元素,也可以自己是一个表。(递归)
实例推荐
1.( 练习册 4.8 )
/* KMP The practice for 4.8
** Author : Kevin
** Date : 2012/02/29
*/
#include"stdio.h"
#include"stdlib.h"
#include"alloc.h"
/* 堆存储 定义*/
typedef struct{
char *ch ;
int length;
}HString ;
/* 字符串初始化 */
int StrAssign( HString *t, char *chars ){
int i ;
char *c;
for(i=0,c=chars; *c!='\0'; ++i,++c); /* 确认 i 值*/
t->ch = (char*)malloc(i*sizeof(char));
t->length = i;
c = chars;
for(i=0; i<t->length; i++){
/*t.ch[i] = c[i];*/
*(t->ch+i) = *(c+i); /* 以上注释也可以 */
printf("%c",t->ch[i]);
}
printf("\n");
return 1;
}
/* 求长度 */
int StrLength( HString t ){
return t.length ;
}
/* 初始化 NEXT 值 */
void InitNext(HString s, int *pn){
int i, j;
pn[1] = 0; /*NEXT[0] = 0 , pn[0] ¼´ NEXT[0]²»´æÔÚ*/
pn[2] = 1; /*NEXT[1] = 1*/
for(i=2; i<=s.length; i++){
j = i ;
do{
if(*(s.ch+(i-1)) == *(s.ch+(pn[j]-1))) {
pn[i+1] = pn[j]+1;
break ;
}
else{
j = pn[j];
}
}while(j != 1);
if(j == 1){
pn[i+1] = 1;
}
}
}
/* 求 下一个Next值 */
int Nextj(int *p, int j){
return *(p+j);
}
/* KMP 算法 */
int KmpString(HString *ps, HString *pm , int pos , int *p){
int i;
int j;
i = pos;
j = 1;
while(i<ps->length && j< pm->length){
if(*(ps->ch+i) == *(pm->ch+j) || j==0){
i++;
j++;
}
else{
j = Nextj(p , j);
}
}
if(j>=pm->length)
return i-pm->length;
else
return 0;
}
int main()
{
char *c = "ADABBADADA";
char *mc = "ADBADABBAABADABBADADA";
int next[10];
int i ;
int kmp_status ;
int sta, stb ;
HString smodel,smain ;
sta = StrAssign(&smodel,c);
stb = StrAssign(&smain,mc);
if(sta){
printf("model is assigned \n");
printf("The model length %d\n",smodel.length);
}else{
printf("model assign error\n");
return 0;
}
if(stb){
printf("main string is assigned \n");
printf("The String length %d\n",smain.length);
}else{
printf("main string assign error\n");
return 0;
}
InitNext(smodel,next);
/*
for(i=0;i<=7;i++)
printf("%d,",next[i]);
*/
printf("\n");
kmp_status = KmpString(&smain, &smodel, 1, next);
if(kmp_status)
printf("It is ok , The Location is %d",kmp_status);
else
printf("This is not matched , sorry ^_^");
getchar();
}
2.( 练习册 4.10 )
/* Reverse String Practice for 4.10
** Author : Kevin
** Date : 2012/02/29
*/
#include"stdio.h"
#include"alloc.h"
#include"stdlib.h"
/* 堆存储 */
typedef struct{
char *ch; /*Store the String*/
int length; /*String's length*/
}HString ;
/* 初始化 String*/
int StrAssign( HString *t, char *chars ){
int i ;
char *c;
for(i=0,c=chars; *c!='\0'; ++i,++c); /* 计算 i 的结果*/
t->ch = (char*)malloc(i*sizeof(char));
t->length = i;
c = chars;
for(i=0; i<t->length; i++){
/*t.ch[i] = c[i];*/
*(t->ch+i) = *(c+i); /* 上面注释的也可以使用*/
printf("%c",t->ch[i]);
}
printf("\n");
return 1;
}
/* 求长度 */
int StrLength( HString t ){
return t.length ;
}
/* 逆置字符串*/
int StrReverse( HString *t ){
int i, j;
char c = '';
i = 0;
j = t->length -1;
while(i<j){
c = *(t->ch+i);
*(t->ch+i) = *(t->ch+j);
*(t->ch+j) = c;
i++;
j--;
}
return 1;
}
int main(){
char *c = "ABCDEF";
int i ;
HString hs ;
StrAssign( &hs ,c);
printf("\n");
printf("%d\n",hs.length);
StrReverse( &hs );
for(i=0; i<hs.length; i++)
printf("%c,",*(hs.ch+i));
getchar();
}
3.( 练习册 4.25 )
/* Replace Operate Practice for 4.25
** Author : Kevin
** Date : 2012/02/29
*/
#include"stdio.h"
#include"stdlib.h"
#include"alloc.h"
/*堆存储*/
typedef struct{
char *ch; /* Store the string */
int length; /* length */
}HString;
/*初始化String*/
int StrAssign( HString *t, char *chars ){
int i ;
char *c;
for(i=0,c=chars; *c!='\0'; ++i,++c); /*求字符串的长度,即 i 值*/
t->ch = (char*)malloc(i*sizeof(char));
t->length = i;
c = chars;
for(i=0; i<t->length; i++){
/*t.ch[i] = c[i];*/
*(t->ch+i) = *(c+i); /* 这种方式和以上的注释的方式都可以*/
printf("%c",t->ch[i]);
}
printf("\n");
return 1;
}
/*返回字符串长度*/
int StrLength( HString t ){
return t.length ;
}
/*指定位置插入字符串*/
int StrInsert(HString *t, int pos, HString s){
int i,j ;
t->ch = (char*)realloc(t->ch,(t->length+s.length)*sizeof(char));
for(i=t->length-1; i>=pos; i--){
*(t->ch+(s.length+i)) = *(t->ch+i);
}
for(j=0; j<s.length; i++,j++){
*(t->ch+pos+j) = *(s.ch+j);
}
t->length = t->length+s.length;
return 1;
}
/*指定位置删除字符串,指定删除长度问题*/
int StrDelete(HString *t, int pos, int len){
int i = 0;
int length = t->length - len ;
for(i=pos; i<t->length-len; i++){
*(t->ch+i) = *(t->ch+i+len);
printf("%d",i);
}
t->length = length;
}
/*销毁字符串*/
void StrDestory(HString *t){
free(t);
}
/*初始化NEXT函数值*/
void InitNext(HString s, int *pn){
int i, j;
pn[1] = 0; /*NEXT[0] = 0 , pn[0] 即 NEXT[0]不存在*/
pn[2] = 1; /*NEXT[1] = 1*/
for(i=2; i<=s.length; i++){
j = i ;
do{
if(*(s.ch+(i-1)) == *(s.ch+(pn[j]-1))) {
pn[i+1] = pn[j]+1;
break ;
}
else{
j = pn[j];
}
}while(j != 1);
if(j == 1){
pn[i+1] = 1;
}
}
}
/*求NEXT函数值*/
int Nextj(int *p, int j){
return *(p+j);
}
/*Kmp算法*/
int KmpString(HString *ps, HString *pm , int pos , int *p){
int i;
int j;
i = pos;
j = 1;
while(i<ps->length && j< pm->length){
if(*(ps->ch+i) == *(pm->ch+j) || j==0){
i++;
j++;
}
else{
j = Nextj(p , j);
}
}
if(j>=pm->length)
return i-pm->length;
else
return 0;
}
int main()
{
char *c = "abaabaf";
char *mc = "abcdababcddabaabafaass";
char *t = "xxx";
int next[7];
int i ;
int kmp_status ;
int sta, stb, stc ;
HString smodel,smain,sx ;
sta = StrAssign(&smodel,c);
stb = StrAssign(&smain,mc);
stc = StrAssign(&sx,t);
if(sta){
printf("model is assigned \n");
printf("The model length %d\n",smodel.length);
}else{
printf("model assign error\n");
return 0;
}
if(stb){
printf("main string is assigned \n");
printf("The String length %d\n",smain.length);
}else{
printf("main string assign error\n");
return 0;
}
if(stc){
printf("Replace string is assigned \n");
printf("The replace length %d\n",sx.length);
}else{
printf("Replace string assign error\n");
return 0;
}
InitNext(smodel,next);
/*
for(i=0;i<=7;i++)
printf("%d,",next[i]);
*/
printf("\n");
kmp_status = KmpString(&smain, &smodel, 1, next);
if(kmp_status){
printf("It is ok , The Location is %d",kmp_status);
StrDelete(&smain, kmp_status,smodel.length);
StrInsert(&smain, kmp_status, sx);
printf("\n");
for(i=0; i<smain.length; i++)
printf("%c,",*(smain.ch+i));
}
else {
printf("This is not matched , sorry ^_^");
}
getchar();
}
4.( 数组练习 )
转置 ( 普通三元组存储 ) , Book 算法 5.1
/* book_5.1
** 普通三元组存储方法,矩阵转置
** Author : Kevin
** Date : 2012/03/01
*/
#include"stdio.h"
#include"stdlib.h"
#include"alloc.h"
#define MAX_SIZE 20
/*三元组结点存储*/
typedef struct {
int i; /* 存储行坐标 */
int j; /* 存储列坐标 */
int elem; /* 存储值 */
}Triple ;
/*矩阵存储结构*/
typedef struct {
Triple data[MAX_SIZE];
int mu; /*行,包括0*/
int nu; /* 列,包括0 */
int tu; /*非0元个数*/
}TSMatrix ;
/*设置矩阵*/
void CreateMatrix(TSMatrix *m, int lm, int lc, int lt)
{
int i ;
m->mu = lm;
m->nu = lc;
m->tu = lt;
for(i=0; i<lt; i++){
printf("Please input the %d values, hang,lie,value\n",i+1);
scanf("%d,%d,%d",&((m->data[i]).i),&((m->data[i]).j),&((m->data[i]).elem));
}
}
/*转置*/
void ReverseMatrix(TSMatrix *m)
{
int i ;
int temp ;
temp = m->mu;
m->mu = m->nu;
m->nu = temp ;
for(i=0; i<m->tu; i++){
temp = m->data[i].i;
m->data[i].i = m->data[i].j;
m->data[i].j = temp;
}
}
/*显示*/
void DisplayMatrix(TSMatrix *m)
{
int i, j, k;
int status = 0;
for(i=1; i<=m->mu; i++){
printf("( ");
for(j=1; j<=m->nu; j++){
for(k=0; k<m->tu; k++){
if((i==m->data[k].i) && (j==m->data[k].j)){
printf("%d ",m->data[k].elem);
status = 1;
break;
}
}
if(status == 0)
printf("0 ");
status = 0;
}
printf(")");
printf("\n");
}
/* 只打印非0元
for(i=0; i<m->tu; i++) {
printf("%d,%d,%d",m->data[i].i,m->data[i].j,m->data[i].elem);
printf("\n");
}
*/
}
int main()
{
TSMatrix m;
CreateMatrix(&m, 3, 4, 4);
DisplayMatrix(&m);
printf("\n");
ReverseMatrix(&m);
DisplayMatrix(&m);
getchar();
getchar();
}
矩阵乘法 ( 采用 行逻辑链接存储方式 ) Book 算法 5.3 ( 只是逻辑链接,并非真正指针链接 )
/* book_5.3
** 行逻辑链接存储方式,矩阵乘法
** Author : Kevin
** Date : 2012/03/01
*/
#include"stdio.h"
#include"stdlib.h"
#include"alloc.h"
#define MAX_SIZE 20
#define MAXRC 10
/*三元组结点存储*/
typedef struct {
int i; /* 存储行坐标 */
int j; /* 存储列坐标 */
int elem; /* 存储值 */
}Triple ;
/*矩阵存储结构*/
typedef struct {
Triple data[MAX_SIZE]; /*存储数据*/
int rpos[MAXRC]; /*记录各行第一个非0元启示位置*/
int mu; /*行,包括0*/
int nu; /* 列,包括0 */
int tu; /*非0元个数*/
}RLSMatrix ;
/*未创建,初始化*/
void Initmatrix(RLSMatrix *m)
{
int i;
m->mu = 0;
m->nu = 0;
m->tu = 0;
for(i=0; i<MAXRC; i++){
m->rpos[i] = -1;
}
}
/*设置矩阵*/
void CreateMatrix(RLSMatrix *m, int lm, int lc, int lt)
{
int i,j ;
m->mu = lm;
m->nu = lc;
m->tu = lt;
for(i=0; i<lt; i++){
printf("Please input the %d values, hang,lie,value\n",i+1);
scanf("%d,%d,%d",&((m->data[i]).i),&((m->data[i]).j),&((m->data[i]).elem));
}
/*增加 设置第一个非0元*/
for(i=1; i<=m->mu; i++){
m->rpos[i] = -1;
for(j=0;j<m->tu;j++){
if(i==m->data[j].i){
m->rpos[i] = j;
break ;
}
}
}
printf("The Matrix not 0 position is \n");
for(i=1; i<=m->mu; i++){
printf("%d ,",m->rpos[i]);
}
printf("\n");
}
/*转置*/
void ReverseMatrix(RLSMatrix *m)
{
int i ;
int temp ;
temp = m->mu;
m->mu = m->nu;
m->nu = temp ;
for(i=0; i<m->tu; i++){
temp = m->data[i].i;
m->data[i].i = m->data[i].j;
m->data[i].j = temp;
}
}
/*矩阵乘法*/
void MultSMatrix(RLSMatrix m1, RLSMatrix m2, RLSMatrix *r)
{
int i;
int hang = 0; /*求rpos*/
int pos = -1;
if (m1.nu != m2.mu)
return 0;
for(i=0; i<m1.tu; i++){
hang = m1.data[i].j;
pos = m2.rpos[hang];
if(pos >= 0 && m1.data[i].j == m2.data[pos].i ){
r->data[r->tu].i = m1.data[i].i;
r->data[r->tu].j = m2.data[pos].j;
r->data[r->tu].elem = r->data[r->tu].elem + m1.data[i].elem * m2.data[pos].elem;
pos++;
r->tu++;
r->mu++;
r->nu++;
}
}
}
/*显示*/
void DisplayMatrix(RLSMatrix *m)
{
int i, j, k;
int status = 0;
for(i=1; i<=m->mu; i++){
printf("( ");
for(j=1; j<=m->nu; j++){
for(k=0; k<m->tu; k++){
if((i==m->data[k].i) && (j==m->data[k].j)){
printf("%d ",m->data[k].elem);
status = 1;
break;
}
}
if(status == 0)
printf("0 ");
status = 0;
}
printf(")");
printf("\n");
}
/* 只打印非0元
for(i=0; i<m->tu; i++) {
printf("%d,%d,%d",m->data[i].i,m->data[i].j,m->data[i].elem);
printf("\n");
}
*/
}
int main()
{
RLSMatrix m , n , r;
CreateMatrix(&m, 3, 4, 4);
CreateMatrix(&n, 4, 2, 4);
Initmatrix(&r);
DisplayMatrix(&m);
printf("\n");
DisplayMatrix(&n);
MultSMatrix(m,n,&r);
printf("\n");
DisplayMatrix(&r);
/*
ReverseMatrix(&m);
DisplayMatrix(&m);
*/
getchar();
getchar();
}
十字链表 存储压缩矩阵 Book 算法 5.4
/* 十字链表 初始化压缩矩阵 Book 算法 5.4
** Author : Kevin
** Date : 2012/03/01
*/
#include"stdio.h"
#include"stdlib.h"
#include"alloc.h"
/*三元组结点存储*/
typedef struct OLNode{
int i; /*行坐标*/
int j; /*列坐标*/
int elem; /*值*/
struct OLNode *down; /*向下指针*/
struct OLNode *right; /*向右指针*/
}OLNode, *OLink ;
/*十字链表存储结构*/
typedef struct{
OLink *rhead; /*行指针,指向行数组,数组是个指针数组,指向行*/
OLink *chead; /*列指针,指向列数组,数组是个指针数组,指向列*/
int mu; /*行,包括 0 元*/
int nu; /*列,包括 0 元*/
int tu; /*非 0 元个数*/
}CrossList;
/*创建十字链表*/
void CreateCrossList(CrossList *pm , int amu, int anu, int atu){
int i;
OLink q = NULL; /*新增加结点时,行指针*/
OLink pc = NULL; /*新增加结点时,列指针*/
OLink pn = NULL; /*新结点指针*/
OLink rprior = NULL; /*保存前一个行指针*/
OLink cprior = NULL; /*保存前一个列指针*/
int hang,lie,value;
pm->mu = amu;
pm->nu = anu;
pm->tu = atu;
pm->rhead = (OLink *)malloc((amu+1)*sizeof(OLink)); /*指针数组,头指针,没有right*/
pm->chead = (OLink *)malloc((anu+1)*sizeof(OLink)); /*指针数组,头指针,没有down*/
for(i=0; i<amu+1; i++){
/*pm->rhead[i] = NULL;*/
*(pm->rhead+i) = NULL;
}
for(i=0; i<anu+1; i++){
/*pm->chead[i] = NULL;*/
*(pm->chead+i) = NULL;
}
for(i=1; i<=atu; i++){
printf("Please input the %d ,hang,lie,value",i);
scanf("%d,%d,%d",&hang,&lie,&value);
pn = (OLink)malloc(sizeof(OLNode));
pn->i = hang;
pn->j = lie;
pn->elem = value;
/*行插入*/
if( *(pm->rhead+hang) == NULL || (*(pm->rhead+hang))->j > pn->j ){
pn->right = *(pm->rhead+hang);
*(pm->rhead+hang) = pn ;
}
else{
for(q = *(pm->rhead+hang); q->right && q->right->j < pn->j; q = q->right);
pn->right = q->right;
q->right = pn ;
}
/*列插入*/
if( *(pm->chead+lie) == NULL || (*(pm->chead+lie))->i > pn->i){
pn->down = *(pm->chead+lie);
*(pm->chead+lie) = pn ;
}
else{
for(q = *(pm->chead+lie); q->down && q->down->i < pn->i; q = q->down);
pn->down = q->down;
q->down = pn ;
}
}
}
/*Display the Matrix*/
void DisplayMatrix(CrossList *pm)
{
int i;
OLink q = NULL;
/*行打印*/
for(i=0; i<pm->mu+1; i++){
q = *(pm->rhead+i);
if(q){
while(q){
printf("%d ",q->elem);
q = q->right;
}
q = NULL;
}else{
continue;
}
}
}
int main(){
CrossList cl;
CreateCrossList(&cl,3,4,4);
DisplayMatrix(&cl);
getchar();
getchar();
}