通过代码快速上手C语言数据结构-数组和广义表

5.1稀疏矩阵转置经典

5.2稀疏矩阵列序递增转置



#include 
#include 
//#include "array.h"
#define MAXSIZE 1000  /*非零元素的个数最多为1000*/
#define ElementType int
/*稀疏矩阵三元组表的类型定义*/	

#define MAXSIZE 1000  /*非零元素的个数最多为1000*/
#define ElementType int
/*稀疏矩阵三元组表的类型定义*/	
typedef struct
{   
	int row,col;  /*该非零元素的行下标和列下标*/
    ElementType e; /*该非零元素的值*/
}Triple;

typedef struct
{  
	Triple data[MAXSIZE+1];   /* 非零元素的三元组表。data[0]未用*/
	int m,n,len;          /*矩阵的行数、列数和非零元素的个数*/
}TSMatrix;

/*矩阵转置的经典算法*/

/*"列序"递增转置法*/

void TransposeTSMatrix(TSMatrix A,TSMatrix *B)
{ /*把矩阵A转置到B所指向的矩阵中去。矩阵用三元组表表示*/
	int i,j,k;
	B->m=A.n; 
	B->n=A.m; 
	B->len=A.len;
	if(B->len>0)
	{
		j=1;				/*j为辅助计数器,记录转置后的三元组在三元组表B中的下标值*/
		for(k=1; k<=A.n; k++) /*扫描三元组表A 共k次,每次寻找列值为k的三元组进行转置*/
			for(i=1; i<=A.len; i++)
				if(A.data[i].col==k)
				{
					B->data[j].row=A.data[i].col;/*从头至尾扫描三元组表A,寻找col值为k的三元组进行转置*/
					B->data[j].col=A.data[i].row;
					B->data[j].e=A.data[i].e;
					j++;		/*计数器j自加,指向下一个存放转置后三元组的下标*/
				}/*内循环中if的结束*/
	}/* if(B->len>0)的结束*/
}/* end of TransposeTSMatrix */

/*"按位快速转置"法*/

void FastTransposeTSMatrix(TSMatrix A,TSMatrix *B)
{ 
	/*基于矩阵的三元组表示,采用"按位快速转置"法,将矩阵A转置为矩阵B*/
	int col,t,p,q;
	int num[MAXSIZE], position[MAXSIZE];
	B->len=A.len; 
	B->n=A.m; 
	B->m=A.n;
	if(B->len)
	{
		for(col=1;col<=A.n;col++)
			num[col]=0;  
		for(t=1;t<=A.len;t++)
			num[A.data[t].col]++; /*计算每一列的非零元素的个数*/	
		position[1]=1;
		for(col=2;col<=A.n;col++)  /*求col列中第一个非零元素在B.data[ ]中的正确位置*/
			position[col]=position[col-1]+num[col-1]; 
		for(p=1;p<=A.len;p++)/*将被转置矩阵的三元组表A从头至尾扫描一次,实现矩阵转置*/
		{  
			col=A.data[p].col;  
			q=position[col];
			B->data[q].row=A.data[p].col;
			B->data[q].col=A.data[p].row;
			B->data[q].e=A.data[p].e;
			position[col]++;/* position[col]加1,指向下一个列号为col的非零元素在三元组表B中的下标值*/
		}/*end of for*/
	}
}


#include 
#include 
//#include "array.h"
#define MAXSIZE 1000  /*非零元素的个数最多为1000*/
#define ElementType int
/*稀疏矩阵三元组表的类型定义*/	



void main()
{
	int i;
	int a[8]={1,1,3,3,4,5,6,6};
	int b[8]={2,3,1,6,3,2,1,4};
	int c[8]={12,9,-3,14,24,18,15,-7};	
	TSMatrix A;
	TSMatrix *B;
	A.n=8; 
	A.m=1; 
	A.len=8;
	B=(TSMatrix *)malloc(sizeof(TSMatrix));
	for(i=0;i<8;i++)
	{
		A.data[i+1].row=a[i];	
		A.data[i+1].col=b[i];
		A.data[i+1].e=c[i];
	}
	TransposeTSMatrix(A,B);	
	for(i=1;i<=8;i++)
	{
		printf("%3d",B->data[i].row);	
	}
	printf("\n");
	for(i=1;i<=8;i++)
	{	
		printf("%3d",B->data[i].col);
	}
	printf("\n");
	for(i=1;i<=8;i++)
	{
		printf("%3d",B->data[i].e);
	}
	printf("\n");
	getchar();
}

void main()
{
	int i;
	int a[8]={1,1,3,3,4,5,6,6};
	int b[8]={2,3,1,6,3,2,1,4};
	int c[8]={12,9,-3,14,24,18,15,-7};	
	TSMatrix A;
	TSMatrix *B;
	A.n=8; 
	A.m=1; 
	A.len=8;
	B=(TSMatrix *)malloc(sizeof(TSMatrix));
	for(i=0;i<8;i++)
	{
		A.data[i+1].row=a[i];	
		A.data[i+1].col=b[i];
		A.data[i+1].e=c[i];
	}
	TransposeTSMatrix(A,B);	
	for(i=1;i<=8;i++)
	{
		printf("%3d",B->data[i].row);	
	}
	printf("\n");
	for(i=1;i<=8;i++)
	{	
		printf("%3d",B->data[i].col);
	}
	printf("\n");
	for(i=1;i<=8;i++)
	{
		printf("%3d",B->data[i].e);
	}
	printf("\n");
	getchar();
}

 

5.3稀疏矩阵—次定位快速转置

#include 
#include 
//#include "array.h"
#define MAXSIZE 1000  /*非零元素的个数最多为1000*/
#define ElementType int
/*稀疏矩阵三元组表的类型定义*/	

#define MAXSIZE 1000  /*非零元素的个数最多为1000*/
#define ElementType int
/*稀疏矩阵三元组表的类型定义*/	
typedef struct
{   
	int row,col;  /*该非零元素的行下标和列下标*/
    ElementType e; /*该非零元素的值*/
}Triple;

typedef struct
{  
	Triple data[MAXSIZE+1];   /* 非零元素的三元组表。data[0]未用*/
	int m,n,len;          /*矩阵的行数、列数和非零元素的个数*/
}TSMatrix;

/*矩阵转置的经典算法*/

/*"列序"递增转置法*/

void TransposeTSMatrix(TSMatrix A,TSMatrix *B)
{ /*把矩阵A转置到B所指向的矩阵中去。矩阵用三元组表表示*/
	int i,j,k;
	B->m=A.n; 
	B->n=A.m; 
	B->len=A.len;
	if(B->len>0)
	{
		j=1;				/*j为辅助计数器,记录转置后的三元组在三元组表B中的下标值*/
		for(k=1; k<=A.n; k++) /*扫描三元组表A 共k次,每次寻找列值为k的三元组进行转置*/
			for(i=1; i<=A.len; i++)
				if(A.data[i].col==k)
				{
					B->data[j].row=A.data[i].col;/*从头至尾扫描三元组表A,寻找col值为k的三元组进行转置*/
					B->data[j].col=A.data[i].row;
					B->data[j].e=A.data[i].e;
					j++;		/*计数器j自加,指向下一个存放转置后三元组的下标*/
				}/*内循环中if的结束*/
	}/* if(B->len>0)的结束*/
}/* end of TransposeTSMatrix */

/*"按位快速转置"法*/

void FastTransposeTSMatrix(TSMatrix A,TSMatrix *B)
{ 
	/*基于矩阵的三元组表示,采用"按位快速转置"法,将矩阵A转置为矩阵B*/
	int col,t,p,q;
	int num[MAXSIZE], position[MAXSIZE];
	B->len=A.len; 
	B->n=A.m; 
	B->m=A.n;
	if(B->len)
	{
		for(col=1;col<=A.n;col++)
			num[col]=0;  
		for(t=1;t<=A.len;t++)
			num[A.data[t].col]++; /*计算每一列的非零元素的个数*/	
		position[1]=1;
		for(col=2;col<=A.n;col++)  /*求col列中第一个非零元素在B.data[ ]中的正确位置*/
			position[col]=position[col-1]+num[col-1]; 
		for(p=1;p<=A.len;p++)/*将被转置矩阵的三元组表A从头至尾扫描一次,实现矩阵转置*/
		{  
			col=A.data[p].col;  
			q=position[col];
			B->data[q].row=A.data[p].col;
			B->data[q].col=A.data[p].row;
			B->data[q].e=A.data[p].e;
			position[col]++;/* position[col]加1,指向下一个列号为col的非零元素在三元组表B中的下标值*/
		}/*end of for*/
	}
}


void main()
{
	int i;
	int a[8]={1,1,3,3,4,5,6,6};
	int b[8]={2,3,1,6,3,2,1,4};
	int c[8]={12,9,-3,14,24,18,15,-7};	
	TSMatrix A;
	TSMatrix *B;
	A.n=8; 
	A.m=1; 
	A.len=8;
	B=(TSMatrix *)malloc(sizeof(TSMatrix));
	for(i=0;i<8;i++)
	{
		A.data[i+1].row=a[i];	
		A.data[i+1].col=b[i];
		A.data[i+1].e=c[i];
	}
	FastTransposeTSMatrix(A,B);	
	for(i=1;i<=8;i++)
	{
		printf("%3d",B->data[i].row);	
	}
	printf("\n");
	for(i=1;i<=8;i++)
	{	
		printf("%3d",B->data[i].col);
	}
	printf("\n");
	for(i=1;i<=8;i++)
	{
		printf("%3d",B->data[i].e);
	}
	getchar();
}

 

5.4建立稀疏矩阵的十字链表

/*建立稀疏矩阵的十字链表的算法*/

//#include "crosslistarray.h"
#include 
#include 
#define NULL 0;
/*十字链表的结构类型定义如下:*/
typedef struct OLNode
{	
	int row,col;        /*非零元素的行和列下标*/
	int value;
	struct OLNode *right;  /*非零元素所在行表、列表的后继链域*/
	struct OLNode *down; 
}OLNode,* OLink;

typedef struct 
{	
	OLink *row_head;  /*行、列链表的头指针向量*/
	OLink *col_head;
	int m,n,len;               /*稀疏矩阵的行数、列数、非零元素的个数*/
}CrossList;



void CreateCrossList(CrossList *M)
{
	int m,n,t;
	OLNode *p,*q;
	int i,j,e;
	/*采用十字链表存储结构,创建稀疏矩阵M*/
	printf("输入M的行数,列数和非零元素的个数\n");
	scanf("%d,%d,%d",&m,&n,&t);  /*输入M的行数,列数和非零元素的个数*/
	M->m=m;
	M->n=n;
	M->len=t;
	if(!(M->row_head=(OLink *)malloc((m+1)*sizeof(OLink)))) 
		printf("error");
	if(!(M->col_head=(OLink *)malloc((n+1)*sizeof(OLink)))) 
		printf("error");
	M->row_head=M->col_head=NULL;   /*初始化行、列头指针向量,各行、列链表为空的链表*/

	printf("输入\n");
	for(scanf("%d,%d,%d",&i,&j,&e);i!=0;scanf("%d,%d,%d",&i,&j,&e))
	{
		if(!(p=(OLNode *)malloc(sizeof(OLNode)))) 
			printf("error");
		p->row=i;
		p->col=j;
		p->value=e;  /*生成结点*/
		if(M->row_head[i]==NULL)   
			M->row_head[i]=p;
		else
		{  
			/*寻找行表中的插入位置*/
			for(q=M->row_head[i];q->right&&q->right->colright);  /*空循环体*/
			p->right=q->right; 
			q->right=p;  /*完成插入*/
		}
		if(M->col_head[j]==NULL)   
			M->col_head[j]=p;
		else
		{  
			/*寻找列表中的插入位置*/
			for(q=M->col_head[j];q->down&&q->down->rowdown);  /*空循环体*/
			p->down=q->down; 
			q->down=p;   /*完成插入*/
		}
	}
}

void main()
{
	CrossList M;

	CreateCrossList(&M);
}

 

5.5求广义表的表头

/*求广义表的表头*/
GList Head(GList L)
{
	if(L==NULL) 
		return(NULL);    /* 空表无表头 */
	if(L->tag==ATOM) 
		exit(0);    /* 原子不是表 */
	else 
		return(L->atom_htp.htp.hp);
}

5.6求广义表的表尾

/*求广义表的表尾*/
GList Tail(GList L)
{
	if(L==NULL) 
		return(NULL);    /* 空表无表尾 */
	if(L->tag==ATOM) 
		exit(0);    /* 原子不是表*/
	else 
		return(L->atom_htp.htp.tp);
}

5.7求广义表的长度

int Length(GList L)
{ 
	int n=0;
	GLNode *s;
	if(L==NULL) 
		return(0);    /* 空表长度为0 */
	if(L->tag==ATOM) 
		exit(0);    /* 原子不是表 */
	s=L;
	while(s!=NULL)    /* 统计最上层表的长度 */
  	{ 
  		k++;
		s=s->atom_htp.htp.tp;
	}
	return(k);
}

5.8求广义表的深度

int Depth(GList L)
{ 
	int d, max;
	GLNode *s;
	if(L==NULL) 
		return(1);    /* 空表深度为1 */
	if(L->tag==ATOM) 
		return(0);    /* 原子深度为0 */
	s=L;
	while(s!=NULL)    /* 求每个子表的深度的最大值 */
	{ 
		d=Depth(s->atom_htp.htp.hp);
		if(d>max) max=d;
    		s=s->atom_htp.htp.tp;
   	}
	return(max+1);    /* 表的深度等于最深子表的深度加1 */
}

5.9-1统计广义表中原子数目方法

int CountAtom(GList L)
{ /*求广义表L中原子结点数目,并返回原子结点数目值*/
	int n;
	GLNode *s;
	if(L==NULL) 
		return(0);    /* 空表中没有原子 */
	if(L->tag==ATOM) 
		return(1);    /* L指向单个原子 */
	s=L; 
	n=0;
	while(s!=NULL)    /* 求每个子表的原子数目之和 */
  	{ 
  		n=n+CountAtom(s->atom_htp.htp.hp);
		s=s->atom_htp.htp.tp;
	}
	return(n);
}

5.9-2统计广义表中原子数目方法

int CountAtom(GList L)
{ 
	int n1, n2;
	if(L==NULL) 
		return(0);    /* 空表中没有原子 */
	if(L->tag==ATOM) 
		return(1);    /* L指向单个原子 */
	n1=CountAtom(L->atom_htp.htp.hp);    /* 求表头中的原子数目 */
	n2=CountAtom(L->atom_htp.htp.tp);    /* 求表尾中的原子数目 */
	return(n1+n2);
}

5.10复制广义表

int CopyGList(GList S, GList *T)
{ 
	if(S==NULL) 
	{ 
		*T=NULL; 
		return(OK); 
	}    /* 复制空表 */
	*T=(GLNode *)malloc(sizeof(GLNode));
	if(*T==NULL) 
		return(ERROR);
	(*T)->tag=S->tag;
	if(S->tag==ATOM) 
		(*T)->atom=S->atom;    /* 复制单个原子 */
	else
	{
		CopyGList(S->atom_htp.htp.hp, &((*T)->atom_htp.htp.hp));    /* 复制表头 */
		CopyGList(S->atom_htp.htp.tp, &((*T)->atom_htp.htp.tp));    /* 复制表尾 */
  	}
	return(OK);
}

 5.5-5.10


//#include "seqstack.h"
#define TRUE 1
#define FALSE 0
#define Stack_Size 50


/*顺序栈-整型*/
typedef struct
{
	int elem[Stack_Size];  /*用来存放栈中元素的一维数组*/
	int  top;          /*用来存放栈顶元素的下标,top为-1表示栈是空栈*/
}nStack;

/*初始化*/
void  nInitStack(nStack *S)
{
/*构造一个空栈S*/
  	S->top=-1;
}

/*判栈空*/
int nIsEmpty(nStack *S)	/*判断栈S为空栈时返回值为真,反之为假*/
{
	return(S->top==-1?TRUE:FALSE);
}

/*判栈满*/
int nIsFull(nStack *S)	/*判断栈S为满栈时返回值为真,反之为假*/
{
	return(S->top==Stack_Size-1?TRUE:FALSE);
}

int nPush(nStack * S, int x)
{
	if(S->top== Stack_Size-1)  return(FALSE);  /*栈已满*/
	S->top++;
	S->elem[S->top]=x;
	return(TRUE);
}

int nPop(nStack * S, int *x)
{  /* 将栈S的栈顶元素弹出,放到x所指的存储空间中 */
	if(S->top==-1)  /*栈为空*/
		return(FALSE);
	else
	{
  		*x= S->elem[S->top];
		S->top--;    /* 修改栈顶指针 */
  		return(TRUE);
	}
}

int nGetTop(nStack *S, int *x)
{  /* 将栈S的栈顶元素弹出,放到x所指的存储空间中,但栈顶指针保持不变 */
	if(S->top==-1)  /*栈为空*/
		return(FALSE);
	else
	{
  		*x = S->elem[S->top];
  		return(TRUE);
	}
}


/*顺序栈-字符型*/
typedef struct
{
	char elem[Stack_Size];  /*用来存放栈中元素的一维数组*/
	int  top;          /*用来存放栈顶元素的下标,top为-1表示栈是空栈*/
}strStack;

/*初始化*/
void strInitStack(strStack *S)
{
/*构造一个空栈S*/
  	S->top=-1;
}

/*判栈空*/
int strIsEmpty(strStack *S)	/*判断栈S为空栈时返回值为真,反之为假*/
{
	return(S->top==-1?TRUE:FALSE);
}

/*判栈满*/
int strIsFull(strStack *S)	/*判断栈S为满栈时返回值为真,反之为假*/
{
	return(S->top==Stack_Size-1?TRUE:FALSE);
}

char strPush(strStack * S, char x)
{
	if(S->top== Stack_Size-1)  return(FALSE);  /*栈已满*/
	S->top++;
	S->elem[S->top]=x;
	return(TRUE);
}

char strPop(strStack * S, char *x)
{  /* 将栈S的栈顶元素弹出,放到x所指的存储空间中 */
	if(S->top==-1)  /*栈为空*/
		return(FALSE);
	else
	{
  		*x= S->elem[S->top];
		S->top--;    /* 修改栈顶指针 */
  		return(TRUE);
	}
}

int strGetTop(strStack *S, char *x)
{  /* 将栈S的栈顶元素弹出,放到x所指的存储空间中,但栈顶指针保持不变 */
	if(S->top==-1)  /*栈为空*/
		return(FALSE);
	else
	{
  		*x = S->elem[S->top];
  		return(TRUE);
	}
}

/*功能函数*/
int Match(char ch,char str)
{		
	if(ch=='('&&str==')')
	{
		return TRUE;
	}
	else if(ch=='['&&str==']')
	{
		return TRUE;
	}
	else if(ch=='{'&&str=='}')
	{
		return TRUE;
	}
	else return FALSE;
}

int In(char ch)
{
	if(ch=='+')
	{
		return TRUE;	
	}
	else if(ch=='-') 
	{
		return TRUE;	
	}
	else if(ch=='*')
	{
		return TRUE;	
	}
	else if(ch=='/')
	{
		return TRUE;	
	}
	else if(ch=='(')
	{
		return TRUE;	
	}
	else if(ch==')')
	{
		return TRUE;	
	}
	else if(ch=='#')
	{
		return TRUE;	
	}
	else return FALSE;
}

char Compare(char x,char ch)
{
	switch(x)
	{
	case '+':
		if(ch=='+'||ch=='-'||ch==')'||ch=='#')
			return '>';	
		else if(ch=='*'||ch=='/'||ch=='(')
				return '<';	
		break;
	case '-':
		if(ch=='+'||ch=='-'||ch==')'||ch=='#')
			return '>';	
		else if(ch=='*'||ch=='/'||ch=='(')
			return '<';	
		break;
	case '*':
		if(ch=='(')
		{
			return '<';
		}
		else
		{
			return '>';
		}
		break;
	case '/':
		if(ch=='(')
				return '<';	
		else
				return '>';	
		break;
	case '(':
		if(ch=='+'||ch=='-'||ch=='*'||ch=='/'||ch=='(')
			return '<';	
		else if(ch==')')
			return '=';	
		else if(ch=='#')
			return '0';	
		break;
	case ')':
		if(ch=='+'||ch=='-'||ch=='*'||ch=='/'||ch==')'||ch=='#')
			return '>';	
		else if(ch=='(')
			return '0';	
		break;
	case '#':
		if(ch=='+'||ch=='-'||ch=='*'||ch=='/'||ch=='(')
			return '<';	
		else if(ch=='#')
			return '=';	
		else if(ch==')')
			return '0';	
		break;	
	default:
		return '0';
		break;
	}

}	

int Execute(int a,char op,int b)
{
	switch(op)
	{
	case '+':
		return (a+b);
		break;
	case '-':
		return (a-b);
		break;
	case '*':
		return (a*b);
		break;
	case '/':
		return (a/b);
		break;
	}
}
#include "stdio.h"
#include 


/*求广义表的表头*/
GList Head(GList L)
{
	if(L==NULL) 
		return(NULL);    /* 空表无表头 */
	if(L->tag==ATOM) 
		exit(0);    /* 原子不是表 */
	else 
		return(L->atom_htp.htp.hp);
}


/*求广义表的表尾*/
GList Tail(GList L)
{
	if(L==NULL) 
		return(NULL);    /* 空表无表尾 */
	if(L->tag==ATOM) 
		exit(0);    /* 原子不是表*/
	else 
		return(L->atom_htp.htp.tp);
}

int Length(GList L)
{ 
	int n=0;
	GLNode *s;
	if(L==NULL) 
		return(0);    /* 空表长度为0 */
	if(L->tag==ATOM) 
		exit(0);    /* 原子不是表 */
	s=L;
	while(s!=NULL)    /* 统计最上层表的长度 */
  	{ 
  		k++;
		s=s->atom_htp.htp.tp;
	}
	return(k);
}

int Depth(GList L)
{ 
	int d, max;
	GLNode *s;
	if(L==NULL) 
		return(1);    /* 空表深度为1 */
	if(L->tag==ATOM) 
		return(0);    /* 原子深度为0 */
	s=L;
	while(s!=NULL)    /* 求每个子表的深度的最大值 */
	{ 
		d=Depth(s->atom_htp.htp.hp);
		if(d>max) max=d;
    		s=s->atom_htp.htp.tp;
   	}
	return(max+1);    /* 表的深度等于最深子表的深度加1 */
}

int CountAtom(GList L)
{ /*求广义表L中原子结点数目,并返回原子结点数目值*/
	int n;
	GLNode *s;
	if(L==NULL) 
		return(0);    /* 空表中没有原子 */
	if(L->tag==ATOM) 
		return(1);    /* L指向单个原子 */
	s=L; 
	n=0;
	while(s!=NULL)    /* 求每个子表的原子数目之和 */
  	{ 
  		n=n+CountAtom(s->atom_htp.htp.hp);
		s=s->atom_htp.htp.tp;
	}
	return(n);
}

int CountAtom(GList L)
{ 
	int n1, n2;
	if(L==NULL) 
		return(0);    /* 空表中没有原子 */
	if(L->tag==ATOM) 
		return(1);    /* L指向单个原子 */
	n1=CountAtom(L->atom_htp.htp.hp);    /* 求表头中的原子数目 */
	n2=CountAtom(L->atom_htp.htp.tp);    /* 求表尾中的原子数目 */
	return(n1+n2);
}

马鞍点

/*如果矩阵A中存在这样的一个元素A[i][j]满足条件:A[i][j]是第i行中值最小的元素,且又是第j列中值最大的
元素,则称之为该矩阵的一个马鞍点。编写一个函数计算出1×n的矩阵A的所有马鞍点。
算法思想:依题意,先求出每行的最小值元素,放入min[m]之中,再求出每列的最大值元素,放入max[n]之中,若某
元素既在min[i]中,又在max[j]中,则该元素A[i][j]便是马鞍点,找出所有这样的元素,即找到了所有马鞍点。因此,
实现本题功能的程序如下:*/
#include 
#define m 3
#define n 3

void minmax(int a[m][n])
{
	int i1,j,have=0;
	int min[m],max[n];
	for(i1=0;i1max [j]) max[j]=a[i1][j];
	}
	for(i1=0;i1

 

你可能感兴趣的:(数据结构与算法)