数组和广义表

 数组和广义表

                   矩阵的快速转置

#include <stdio.h>

#include <stdlib.h>

#define MAXSIZE 30

typedef struct

{

    int i;//行号

    int j;//列号

    int v;//非零元素之

}TNode;//三元组类型

typedef struct

{

int m;//矩阵行数

int n;//矩阵列数

int t;//矩阵中非零元素个数

TNode data[MAXSIZE];//三元组表

}TSMatrix;//三元组表类型

void CreatMat(TSMatrix *p,inta[3][4],int m,int n)//建立三元组表

{

    int i,j;

    p->m=m;

    p->n=n;

    p->t=0;//p->t指向三元组表的第一个三元组位置

    for(i=0;i<m;i++)

    {

        for(j=0;j<n;j++)

        if(a[i][j]!=0)//将非零元素存储于三元组表data中

        {

            p->data[p->t].i=i;

            p->data[p->t].j=j;

            p->data[p->t].v=a[i][j];

            p->t++;//下标加1以便三元组表a存放下一个非零元素

        }

    }

}

void FastTranTat(TSMatrix*a,TSMatrix *b)//矩阵快速转置

{

    int i,k,pot[MAXSIZE];

    b->m=a->m;

    b->n=a->n;

    b->t=a->t;

    if(b->t!=0)//当三元组表不为空时

    {

        for(k=1;k<a->n;k++)

        pot[k]=0;//pot数组初始化

        for(i=0;i<a->t;i++)

        {

            k=a->data[i].j;

            pot[k+1]=pot[k+1]+1;//统计第k列非零元素的个数并送入pot[k+1]

        }

        pot[0]=0;//第0列第一个非零元素在表b中的位置

        for(k=1;k<a->n;k++)

        pot[k]=pot[k-1]+pot[k];//第1··第n-1列第一个非零元素在表b中的存放位置

        for(i=0;i<a->t;i++)

        {

            k=a->data[i].j;

           b->data[pot[k]].i=a->data[i].j;

            b->data[pot[k]].j=a->data[i].i;

           b->data[pot[k]].v=a->data[i].v;

            pot[k]=pot[k]+1;//第k列的存放位置加1,准备存放地k列的下一个三元组

        }

    }

}

void main()

{

    TSMatrix *p,*q;

    inti,a[3][4]={{0,3,1,0},{1,0,0,0},{0,2,0,1}};

    p=(TSMatrix *)malloc(sizeof(TSMatrix));

    q=(TSMatrix *)malloc(sizeof(TSMatrix));

    CreatMat(p,a,3,4);

    printf("   i  j   data\n");

    for(i=0;i<p->t;i++)

   printf("%4d%4d%4d\n",p->data[i].i,p->data[i].j,p->data[i].v);

    FastTranTat(p,q);

    printf("After tsmatrix:\n");

    printf("   i  j   data:\n");

    for(i=0;i<q->t;i++)

   printf("%4d%4d%4d\n",q->data[i].i,p->data[i].j,p->data[i].v);

}

                         矩阵转置

#include <stdio.h>

#include <stdlib.h>

#define MAXSIZE 30

typedef struct

{

    int i;//行号

    int j;//列号

    int v;//非零元素值

}TNode;//三元组类型

typedef struct

{

    int m;//矩阵行数

    int n;//矩阵列数

    int t;//矩阵中非零元素个数

    TNode data[MAXSIZE];//三元组表

}TSMatrix;//三元组表类型

void CreatMat(TSMatrix *p,inta[3][4],int m,int n)//建立三元数组表

{

    int i;

    int j;

    p->m=m;

    p->n=n;

    p->t=0;//p->t指向三元组表data的第一个三元组位置0

    for(i=0;i<m;i++)

    {

        for(j=0;j<n;j++)

        if(a[i][j]!=0)//将非零元素存储于三元组表data中

        {

            p->data[p->t].i=i;

            p->data[p->t].j=j;

            p->data[p->t].v=a[i][j];

            p->t++;//下标加1使三元组表a 存放下一个非零元素

        }

    }

}

void TranTat(TSMatrix*a,TSMatrix *b)//在三元组表的存储方式下,实现矩阵的转置

{

    int k,p,q;//k指向三元组表a的列号;p,q分别为指示三元组a和b的下标

    b->m=a->m;

    b->n=a->n;

    b->t=a->t;

    if(b->t!=0)//当三元组表不为空

    {

        q=0;//由三元组b的第一个三元组位置0开始

        for(k=0;k<a->n;k++)//对三元组表a按下列下标由小到大进行扫描

        {

            for(p=0;p<a->t;p++)//按表长扫描整个三元组表

            if(a->data[p].j==k)

            {

               b->data[q].i=a->data[p].j;

                b->data[q].j=a->data[p].i;

               b->data[q].v=a->data[p].v;

                q++;

            }

        }

    }

}

void main()

{

    TSMatrix *p,*q;

    inti,a[3][4]={{0,3,1,0},{1,0,0,0},{0,2,0,1}};

    p=(TSMatrix *)malloc(sizeof(TSMatrix));//生成三元组表存储空间

    q=(TSMatrix *)malloc(sizeof(TSMatrix));//生成转制后的三元组表存储空间

    CreatMat(p,a,3,4);//生成矩阵的三元组表

    printf("Befor tsmarix:\n");//输出三元组表

    printf("   i  j   data\n");

    for(i=0;i<p->t;i++)

    printf("%4d%4d%4d\n",p->data[i].i,p->data[i].j,p->data[i].v);

    TranTat(p,q);//进行矩阵的转置

    printf("After tsmatrix:\n");

    printf("   i  j   data\n");

    for(i=0;i<q->t;i++)

   printf("%4d%4d%4d\n",q->data[i].i,q->data[i].j,q->data[i].v);

}

                   生成广义表及求广义表长度、深度

#include <stdio.h>

#include <stdlib.h>

#define MAXSIZE 30

typedef struct

{

    char data[MAXSIZE];

    int top;

}SeqStack;//顺序栈类型

void Init_SeqStack(SeqStack**s)//顺序栈初始化

{

    *s=(SeqStack *)malloc(sizeof(SeqStack));//在主调函数中申请栈空间

    (*s)->top=-1;//置栈空标志

}

int Empty_SeqStack(SeqStack*s)//判栈空

{

    if(s->top==-1)//栈为空时

    return 1;

    else

    return 0;

}

void Push_SeqStack(SeqStack*s,char x)//元素入栈

{

    if(s->top==MAXSIZE-1)

    printf("Stack is full\n");//栈已满

    else

    {

        s->top++;

        s->data[s->top]=x;//元素x压入栈中

    }

}

void Pop_SeqStack(SeqStack*s,char *x)//元素出栈

{

    if(s->top==-1)

    printf("Stack is empty!\n");//栈为空

    else

    {

        *x=s->data[s->top];//栈顶元素出栈

        s->top--;

    }

}

void Top_SeqStack(SeqStack*s,char *x)//度栈顶元素

{

    if(s->top==-1)

    printf("Staack is empty!\n");

    else

    *x=s->data[s->top];

}

typedef struct node

{

    int flag;//标志域

    union//元素结点和表结点共用内存

    {

        char data;//元素结点数据域

        struct node *hp;//表结点的头指针

    }val;

    struct node *tp;//指向下一个兄弟节点

}CBNode;//广义表结点类型

CBNode *Create(char ex[])//用孩子兄弟表示法建立广义表)

{

    CBNode *p,*q=NULL,*h,*hp[MAXSIZE];//h为最终生成的广义表表头指针

    SeqStack *s;

    char x,*y=&x;//出栈元素经过指针y指向x

    int i=0,j=0,b=0,t=0,k=0;

    Init_SeqStack(&s);

    while(ex[i]!='\0')//是否到表达式串的串尾

    {

        if(ex[i]==' ')//当前字符为空格字符是

        i++;

        if(ex[i]=='(')

           {

               Push_SeqStack(s,ex[i]);

               p=(CBNode*)malloc(sizeof(CBNode));

               p->flag=1;//新结点作为表头结点

               p->tp=NULL;//表元素结点的tp指针暂置为空

               k=0;//表元素结点标志

               hp[j++]=p;//将指向表元素的指针p压入hp中

               if(q!=NULL)

               if(t==1)

               {

                   t=0;

                   q->tp=p;//结点*p作为*q兄弟结点链入链表

               }

               else

               q->val.hp=p;//结点*p作为*q孩子节点链入表中

               else

               q=p;//指针q下移指向结点*p

               if(b==0)//刚生成的广义表的第一个结点

               {

                   h=p;

                   b=1;//使广义表指针h指向该节点

               }

           }

           else

           if(ex[i]==')')//字表结束

           {

               Top_SeqStack(s,y);

               if(*y=='(')

                  {

                      p->tp=NULL;

                     if(ex[i-1]=='('||(ex[i-1]==' '&&ex[i-2]=='('))//空表时的处理

                                   p->val.hp=NULL;//子表是空表

                                   Pop_SeqStack(s,y);

                                    if(j!=0)//当栈hp未到栈底

                                    {

                                       q=hp[--j];//将保存于hp的表元素结点指针弹出赋给q

                                       if(ex[i+1]==',')

                                        {

                                       if(ex[i+2]=='(')//下一个兄弟节点是表示元素结点的处理

                                              {

                                                  t=1;k=0;i++;

                                                  goto 12;

                                              }

                                               i++;

                                        }

                                        k=1;//下一兄弟节点是氮元素结点的处理

                                        12: ;

                                    }

                  }

                  else

                  {

                      h=NULL;//输入的广义表字符串有错,置广义表为空

                     printf("Error!\n");

                      goto 11;

                  }

           }

           else

           if(ex[i]!=',')//生成单元素结点的处理

           {

               if(k==0)//在此之前生成的*p为表元素结点

               {

                   q=p;//使q指向这个表元素结点

                   k=0;

               }

               p=(CBNode*)malloc(sizeof(CBNode));//创建新节点

               p->flag=0;//新结点作为单元素结点

               p->val.data=ex[i];

               if(ex[i-1]=='(')

                  q->val.hp=p;//作为孩子节点链接到当前节点上

                  else

                  q->tp=p;//作为兄弟节点连接到当前结点

           }

           else

           {

               q=p;

               t=1;

           }

           i++;

    }

    if(!Empty_SeqStack(s))//栈s不为空则(与)不匹配,即输入串有错

    {

        h=NULL;

        printf("Error!\n");

    }

    11: return h;//返回广义表头指针

}

int CBLength(CBNode *h)//求广义表的头指针

{

    int n=0;

    h=h->val.hp;//h指向广义表的第一个元素

    while(h!=NULL)

    {

        n++;

        h=h->tp;

    }

    return n;//n为广义表的长度

}

int CBDepth(CBNode *h)//求广义表的深度

{

    int max=0,dep;//置深度初值为0

    if(h->flag==0)//为单元素时返回0

    return 0;

    h=h->val.hp;//h指向广义表的第一个元素

    if(h==NULL)//子表为空时返回1

    return 1;

    while(h!=NULL)//遍历表中的每一个元素

    {

        if(h->flag==1)//元素为表结点时

        {

            dep=CBDepth(h);//递归调用求出子表的深度

            if(dep>max)//max为同一层所求子表中的深度最大值

            max=dep;

        }

        h=h->tp;//使h指向下一个元素值

    }

    return max+1;//返回表的深度

}

void DispcB(CBNode *h)//输出广义表

{

    if(h!=NULL)//表非空

    {

        if(h->flag==1)//为表结点时

        {

            printf("(");

            if(h->val.hp==NULL)

            printf(" ");//输出空子表

            else

            DispcB(h->val.hp);//递归输出子表

        }

        else

       printf("%c",h->val.data);//为单元素时输出元素值

        if(h->flag==1)

        printf(")");

        if(h->tp!=NULL)//有后继结点时

        {

            printf(",");//输出间隔符

            DispcB(h->tp);//递归输出后继元素的结点信息

        }

    }

}

void main()

{

    char c[MAXSIZE];

    CBNode *h;//定义广义表类型指针变量h

    printf("Input lists:\n");

    gets(c);//输入广义表字符串

    h=Create(c);//根据字符串建立广义表

    DispcB(h);//输出广义表

    printf("\n");

    printf("Length of lists is%d\n",CBLength(h));//输出广义表长度

    printf("Depth of lists is%d\n",CBDepth(h));//输出广义表的深度

}

                        稀疏矩阵的十字链表存储

#include <stdio.h>

#include <stdlib.h>

#define MAXSIZE 10

typedef struct node

{

    int row,col;//row和col为非零元素所在的行和列

    struct node *down,*right;//right和down为非零元素结点的行、列指针

    union

    {

        int v;//v为非零元素的值

        struct node *next;//next为头结点链表指针

    }tag;

}MNode;//十字链表结点类型

void print(MNode *h[],intm,int n)//输出十字链表

{

    MNode *p;

    int i;

    printf("十字链表的行链表:\n");

    for(i=0;i<m;i++)

    {

        p=h[i]->right;

        printf("H%d:  ",i);

        while(p!=h[i])

        {

           printf("(%d,%d):%d,",p->row,p->col,p->tag.v);

            p=p->right;

        }

        printf("\n");

    }

    printf("十字链表的列链表:\n");

    for(i=0;i<n;i++)

    {

        p=h[i]->down;

        printf("H%d:   ",i);

        while(p!=h[i])

        {

           printf("(%d,%d):%d",p->row,p->col,p->tag.v);

            p=p->down;

        }

        printf("\n");

    }

}

void CreatMat(MNode**mh,MNode *h[])//建立稀疏矩阵的十字链表

{

    MNode *p,*q;//p和q为暂存指针

    int i,j,k,m,n,t,v,max;//设非零元素的值v为整形

    printf("Input m,n,t:");

   scanf("%d,%d,%d",&m,&n,&t);

    *mh=(MNode *)malloc(sizeof(MNode));//创建头结点循环链表的头结点

    (*mh)->row=m;//存储矩阵的行数

    (*mh)->col=n;//存储矩阵的列数

    p=*mh;//指针p指向头结点*mh

    if(m>n)

    max=m;//如果行数大雨列数则将行数值赋给max

    else

    max=n;//如果列数大雨行数将值赋给max

    for(i=0;i<max;i++)//采用尾插法创建头结点

    {

        h[i]=(MNode *)malloc(sizeof(MNode));

        h[i]->down=h[i];//初始时down指向头结点自身

        h[i]->right=h[i];//初始时right指向头结点自身

        h[i]->row=-1;

        h[i]->col=-1;

        p->tag.next=h[i];//降头结点连接起来形成一个链表

        p=h[i];

    }

    p->tag.next=*mh;//将最后插入的头结点中的next指针再指向揽投形成头结点循环链表

    for(k=0;k<t;k++)

    {

        printf("Input i,j,v:");

       scanf("%d,%d,%d",&i,&j,&v);//输入一个三元组

        p=(MNode *)malloc(sizeof(MNode));

        p->row=i;

        p->col=j;

        p->tag.v=v;//以下实现将*p插入到底i行链表中区,且按列号有序

        q=h[i];

       while(q->right!=h[i]&&q->right->col<j);//按列号找到位置插入

        q=q->right;

        p->right=q->right;//完成插入

        q->right=p;//以下实现将*p插入到第j列链表中去,且按行号有序

        q=h[j];

       while(q->down!=h[j]&&q->down->row<i)//按行号找到插入位置

        q=q->down;

        p->down=q->down;//完成插入

        q->down=p;

    }

    print(h,m,n);//输出十字链表

}

void main()

{

    MNode *mh,*h[MAXSIZE];

    CreatMat(&mh,h);//建立十字链表

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值