void SubtSMatrix(CrossList M,CrossList N,CrossList *Q) { /* 初始条件:稀疏矩阵M与N的行数和列数对应相等。操作结果:求稀疏矩阵的差Q=M-N */ int i; OLink pq,pm,pn; if(M.mu!=N.mu||M.nu!=N.nu) { printf("两个矩阵不是同类型的,不能相减\n"); exit(OVERFLOW); } (*Q).mu=M.mu; /* 初始化Q矩阵 */ (*Q).nu=M.nu; (*Q).tu=0; /* Q矩阵元素个数的初值为0 */ InitSMatrixList(Q); /* 初始化Q的表头指针向量 */ for(i=1;i<=M.mu;i++) /* 按行的顺序相减 */ { pm=M.rhead[i]; /* pm指向矩阵M的第i行的第1个结点 */ pn=N.rhead[i]; /* pn指向矩阵N的第i行的第1个结点 */ while(pm&&pn) /* pm和pn均不空 */ { pq=(OLink)malloc(sizeof(OLNode)); /* 生成矩阵Q的结点 */ switch(comp(pm->j,pn->j)) { case -1: *pq=*pm; /* M的列<N的列,将矩阵M的当前元素值赋给pq */ InsertAscend(Q,pq); /* 将结点pq按行列值升序插到矩阵Q中 */ pm=pm->right; /* 指针向后移 */ break; case 0: *pq=*pm; /* M、N矩阵的列相等,元素值相减 */ pq->e-=pn->e; if(pq->e!=0) /* 差为非零元素 */ InsertAscend(Q,pq); /* 将结点pq按行列值升序插到矩阵Q中 */ else free(pq); /* 释放结点 */ pm=pm->right; /* 指针向后移 */ pn=pn->right; break; case 1: *pq=*pn; /* M的列>N的列,将矩阵N的当前元素值赋给pq */ pq->e*=-1; /* 求反 */ InsertAscend(Q,pq); /* 将结点pq按行列值升序插到矩阵Q中 */ pn=pn->right; /* 指针向后移 */ } } while(pm) /* pn=NULL */ { pq=(OLink)malloc(sizeof(OLNode)); /* 生成矩阵Q的结点 */ *pq=*pm; /* M的列<N的列,将矩阵M的当前元素值赋给pq */ InsertAscend(Q,pq); /* 将结点pq按行列值升序插到矩阵Q中 */ pm=pm->right; /* 指针向后移 */ } while(pn) /* pm=NULL */ { pq=(OLink)malloc(sizeof(OLNode)); /* 生成矩阵Q的结点 */ *pq=*pn; /* M的列>N的列,将矩阵N的当前元素值赋给pq */ pq->e*=-1; /* 求反 */ InsertAscend(Q,pq); /* 将结点pq按行列值升序插到矩阵Q中 */ pn=pn->right; /* 指针向后移 */ } } if((*Q).tu==0) /* Q矩阵元素个数为0 */ DestroySMatrix(Q); /* 销毁矩阵Q */ }
void main() { SqList L; ElemType d,e; Status i; int n; printf("按非降序建立n个元素的线性表L,请输入元素个数n: "); scanf("%d",&n); CreatAscend(L,n); printf("依次输出L的元素:"); ListTraverse(L,visit); InsertAscend(L,10); // 按非降序插入元素10 printf("按非降序插入元素10后,线性表L为:"); ListTraverse(L,visit); HeadInsert(L,12); // 在L的头部插入12 EndInsert(L,9); // 在L的尾部插入9 printf("在L的头部插入12,尾部插入9后,线性表L为:"); ListTraverse(L,visit); printf("请输入要删除的元素的值: "); cin>>e; i=DeleteElem(L,e); if(i) cout<<"成功删除"<<e<<'!'<<endl; else cout<<"不存在元素"<<e<<'!'<<endl; printf("线性表L为:"); ListTraverse(L,visit); printf("请输入要取代的元素的序号 元素的新值: "); cin>>n>>e; ReplaceElem(L,n,e); printf("线性表L为:"); ListTraverse(L,visit); DestroyList(L); printf("销毁L后,按非升序重新建立n个元素的线性表L,请输入元素个数n(>2):"); scanf("%d",&n); CreatDescend(L,n); printf("依次输出L的元素:"); ListTraverse(L,visit); InsertDescend(L,10); // 按非升序插入元素10 printf("按非升序插入元素10后,线性表L为:"); ListTraverse(L,visit); printf("请输入要删除的元素的值: "); cin>>e; i=DeleteElem(L,e); if(i) cout<<"成功删除"<<e<<'!'<<endl; else cout<<"不存在元素"<<e<<'!'<<endl; printf("线性表L为:"); ListTraverse(L,visit); DeleteFirst(L,e); DeleteTail(L,d); cout<<"删除表头元素"<<e<<"和表尾元素"<<d<<"后,线性表L为:"<<endl; ListTraverse(L,visit); }
void main() { SqList L; ElemType d,e; Status i; int n; printf("按非降序建立n个元素的线性表L,请输入元素个数n: "); scanf("%d",&n); CreatAscend(&L,n); printf("依次输出L的元素:"); ListTraverse(L,visit); InsertAscend(&L,10); /* 按非降序插入元素10 */ printf("按非降序插入元素10后,线性表L为:"); ListTraverse(L,visit); HeadInsert(&L,12); /* 在L的头部插入12 */ EndInsert(&L,9); /* 在L的尾部插入9 */ printf("在L的头部插入12,尾部插入9后,线性表L为:"); ListTraverse(L,visit); printf("请输入要删除的元素的值: "); scanf("%d",&e); i=DeleteElem(&L,e); if(i) printf("成功删除%d\n",e); else printf("不存在元素%d!\n",e); printf("线性表L为:"); ListTraverse(L,visit); printf("请输入要取代的元素的序号 元素的新值: "); scanf("%d%d",&n,&e); ReplaceElem(L,n,e); printf("线性表L为:"); ListTraverse(L,visit); DestroyList(&L); printf("销毁L后,按非升序重新建立n个元素的线性表L,请输入元素个数n(>2): "); scanf("%d",&n); CreatDescend(&L,n); printf("依次输出L的元素:"); ListTraverse(L,visit); InsertDescend(&L,10); /* 按非升序插入元素10 */ printf("按非升序插入元素10后,线性表L为:"); ListTraverse(L,visit); printf("请输入要删除的元素的值: "); scanf("%d",&e); i=DeleteElem(&L,e); if(i) printf("成功删除%d\n",e); else printf("不存在元素%d!\n",e); printf("线性表L为:"); ListTraverse(L,visit); DeleteFirst(&L,&e); DeleteTail(&L,&d); printf("删除表头元素%d和表尾元素%d后,线性表L为:\n",e,d); ListTraverse(L,visit); }
void CreateSMatrix(CrossList *M) { /* 创建稀疏矩阵M,采用十字链表存储表示。算法5.4改 */ int i,k; OLink p; if((*M).rhead) DestroySMatrix(M); printf("请输入稀疏矩阵的行数 列数 非零元个数: "); scanf("%d%d%d",&(*M).mu,&(*M).nu,&i); InitSMatrixList(M); /* 初始化M的表头指针向量 */ printf("请按任意次序输入%d个非零元的行 列 元素值:\n",(*M).tu); for(k=0;k<i;k++) { p=(OLink)malloc(sizeof(OLNode)); /* 生成结点 */ if(!p) exit(OVERFLOW); scanf("%d%d%d",&p->i,&p->j,&p->e); /* 给结点的3个成员赋值 */ InsertAscend(M,p); /* 将结点p按行列值升序插到矩阵M中 */ } }
void MultSMatrix(CrossList M,CrossList N,CrossList *Q) { /* 初始条件:稀疏矩阵M的列数等于N的行数。操作结果:求稀疏矩阵乘积Q=M×N */ int i,j,e; OLink pq,pm,pn; InitSMatrix(Q); (*Q).mu=M.mu; (*Q).nu=N.nu; (*Q).tu=0; InitSMatrixList(Q); /* 初始化Q的表头指针向量 */ for(i=1;i<=(*Q).mu;i++) for(j=1;j<=(*Q).nu;j++) { pm=M.rhead[i]; pn=N.chead[j]; e=0; while(pm&&pn) switch(comp(pn->i,pm->j)) { case -1: pn=pn->down; /* 列指针后移 */ break; case 0: e+=pm->e*pn->e; /* 乘积累加 */ pn=pn->down; /* 行列指针均后移 */ pm=pm->right; break; case 1: pm=pm->right; /* 行指针后移 */ } if(e) /* 值不为0 */ { pq=(OLink)malloc(sizeof(OLNode)); /* 生成结点 */ if(!pq) /* 生成结点失败 */ exit(OVERFLOW); pq->i=i; /* 给结点赋值 */ pq->j=j; pq->e=e; InsertAscend(Q,pq); /* 将结点pq按行列值升序插到矩阵Q中 */ } } if((*Q).tu==0) /* Q矩阵元素个数为0 */ DestroySMatrix(Q); /* 销毁矩阵Q */ }
void CopySMatrix(CrossList M,CrossList *T) { /* 初始条件:稀疏矩阵M存在。操作结果:由稀疏矩阵M复制得到T */ int i; OLink p,q; if((*T).rhead) /* 矩阵T存在 */ DestroySMatrix(T); (*T).mu=M.mu; (*T).nu=M.nu; InitSMatrixList(T); /* 初始化T的表头指针向量 */ for(i=1;i<=M.mu;i++) /* 按行复制 */ { p=M.rhead[i]; /* p指向i行链表头 */ while(p) /* 没到行尾 */ { q=(OLNode*)malloc(sizeof(OLNode)); /* 生成结点q */ if(!q) exit(OVERFLOW); *q=*p; /* 给结点q赋值 */ InsertAscend(T,q); /* 将结点q按行列值升序插到矩阵T中 */ p=p->right; } } }
/* 并返回TRUE;如无此元素,则返回FALSE */ *p=L; while(*p) { *q=(*p)->next; if(*q&&!strcmp((*q)->data.name,name)) /* 找到该姓名 */ return TRUE; *p=*q; } return FALSE; } Status DeleteElemNum(LinkList L,long num) { /* 删除表中学号为num的元素,并返回TRUE;如无此元素,则返回FALSE */ LinkList p,q; if(FindFromNum(L,num,&p,&q)) /* 找到此结点,且q指向其,p指向其前驱 */ { p->next=q->next; free(q); return TRUE; } return FALSE; } Status DeleteElemName(LinkList L,char name[]) { /* 删除表中姓名为name的元素,并返回TRUE;如无此元素,则返回FALSE */ LinkList p,q; if(FindFromName(L,name,&p,&q)) /* 找到此结点,且q指向其,p指向其前驱 */ { p->next=q->next; free(q); return TRUE; } return FALSE; } void Modify(ElemType *e) { /* 修改结点内容 */ char s[80]; Print(*e); /* 显示原内容 */ printf("请输入待修改项的内容,不修改的项按回车键保持原值:\n"); printf("请输入姓名(<=%d个字符): ",NAMELEN); gets(s); if(strlen(s)) strcpy(e->name,s); printf("请输入学号: "); gets(s); if(strlen(s)) e->num=atol(s); printf("请输入性别(m:男 f:女): "); gets(s); if(strlen(s)) e->sex=s[0]; printf("请输入年龄: "); gets(s); if(strlen(s)) e->age=atoi(s); printf("请输入班级(<=%d个字符): ",CLASSLEN); gets(s); if(strlen(s)) strcpy(e->Class,s); printf("请输入健康状况(0:%s 1:%s 2:%s):",sta[0],sta[1],sta[2]); gets(s); if(strlen(s)) e->health=atoi(s); /* 修改完毕 */ } #define N 4 /* student记录的个数 */ void main() { struct stud student[N]={{"王小林",790631,'m',18,"计91",0}, {"陈红",790632,'f',20,"计91",1}, {"刘建平",790633,'m',21,"计91",0}, {"张立立",790634,'m',17,"计91",2}}; /* 表的初始记录 */ int i,j,flag=1; long num; char filename[13],name[NAMELEN+1]; ElemType e; LinkList T,p,q; InitList(&T); /* 初始化链表 */ while(flag) { printf("1:将结构体数组student中的记录按学号非降序插入链表\n"); printf("2:将文件中的记录按学号非降序插入链表\n"); printf("3:键盘输入新记录,并将其按学号非降序插入链表\n"); printf("4:删除链表中第一个有给定学号的记录\n"); printf("5:删除链表中第一个有给定姓名的记录\n"); printf("6:修改链表中第一个有给定学号的记录\n"); printf("7:修改链表中第一个有给定姓名的记录\n"); printf("8:查找链表中第一个有给定学号的记录\n"); printf("9:查找链表中第一个有给定姓名的记录\n"); printf("10:显示所有记录 11:将链表中的所有记录存入文件 12:结束\n"); printf("请选择操作命令: "); scanf("%d",&i); switch(i) { case 1: for(j=0;j<N;j++) InsertAscend(T,student[j]); break; case 2: printf("请输入文件名: "); scanf("%s",filename); if((fp=fopen(filename,"rb"))==NULL) printf("打开文件失败!\n"); else { while(ReadFromFile(&e)) InsertAscend(T,e); fclose(fp); } break; case 3: ReadIn(&e); InsertAscend(T,e); break; case 4: printf("请输入待删除记录的学号: "); scanf("%ld",&num); if(!DeleteElemNum(T,num)) printf("没有学号为%ld的记录\n",num); break; case 5: printf("请输入待删除记录的姓名: "); scanf("%s",name); if(!DeleteElemName(T,name)) printf("没有姓名为%s的记录\n",name); break; case 6: printf("请输入待修改记录的学号: "); scanf("%ld%*c",&num); /* %*c吃掉回车符 */ if(!FindFromNum(T,num,&p,&q)) printf("没有学号为%ld的记录\n",num); else { Modify(&q->data); if(q->data.num!=num) /* 学号被修改 */ { p->next=q->next; /* 把q所指的结点从L中删除 */ InsertAscend(T,q->data); /* 把元素插入L */ free(q); /* 删除q */ } } break; case 7: printf("请输入待修改记录的姓名: "); scanf("%s%*c",name); /* %*c吃掉回车符 */ if(!FindFromName(T,name,&p,&q)) printf("没有姓名为%s的记录\n",name); else { num=q->data.num; /* 学号存入num */ Modify(&q->data); if(q->data.num!=num) /* 学号被修改 */ { p->next=q->next; /* 把q所指的结点从L中删除 */ InsertAscend(T,q->data); /* 把元素插入L */ free(q); /* 删除q */ } } break; case 8: printf("请输入待查找记录的学号: "); scanf("%ld",&num); if(!FindFromNum(T,num,&p,&q)) printf("没有学号为%ld的记录\n",num); else Print(q->data); break; case 9: printf("请输入待查找记录的姓名: "); scanf("%s",name); if(!FindFromName(T,name,&p,&q)) printf("没有姓名为%s的记录\n",name); else Print(q->data); break; case 10:printf(" 姓名 学号 性别 年龄 班级 健康状况\n"); ListTraverse(T,Print); break; case 11:printf("请输入文件名: "); scanf("%s",filename); if((fp=fopen(filename,"wb"))==NULL) printf("打开文件失败!\n"); else ListTraverse(T,WriteToFile); fclose(fp); break; case 12:flag=0; } } }