C语言练习记录(持续更新)

记录一下本人在学习C语言时做的有价值的部分小练习,持续更新.

(1)计算1/2+1/3+...+1/n=1

// this is a code calculating s=1/2+1/3+1/4+...+1/n=1

#include<stdio.h>
int main()
{
    int n,m;
    double s,d;
    printf("enter the number of loop:");
    scanf("%d",&n);
    for (s=0,m=1,d=2;m<=n;m+=1,d*=2)
    {
        s+=1/d;
        printf("when loop =%d,d=%f,s=%f\n ",m,d,s);
    }
    return 0;

}

(2)计算浮点类型数的正整数次方

// this is a code calculating the positive power of a number
#include<stdio.h>
float power(float n,int p);
int main()
{
    float di;
    int zhi;

    printf("please enter the dishiu and the zhisu(char or negtive number to quit");
    while(scanf("%f%d",&di,&zhi)==2&&zhi>0)
    {
        printf("%f to the %dth power is %f\n",di,zhi,power(di,zhi));
        printf("please enter another group of number(char or negtive number to quit)");
    }
    printf("quit successfully\n");
}
float power(float n,int p)
{
    int i;
    float pow=1;
    for(i=1;i<=p;i++)
        pow*=n;
    return pow;
}

(3)ABA型金字塔

#include<stdio.h>
int main()
{
    char CH;int CHn;
    printf("please enter a character between A-Z");
    CH=getchar();CHn=(int)CH-64;
    // CHn确定程序有多少行,用于第一个for循环
    int hang,lie;
    for(hang=1,lie=1;hang<=CHn;hang++,lie=hang)
    {
        for( ;lie<CHn;lie++)
            printf(" ");
        char ch;
        int a;
        for(a=1,ch='A';a<=hang;ch++,a++)
            printf("%c",ch);
        ch=ch-2;
        for(a=1;a<hang;ch--,a++)
            printf("%c",ch);
        printf("\n");
    }
    return 0;
}

(4)输入字符串,倒序输出字符串.此时要注意,字符串的最后一个单元储存‘\0',所以定义时要注意单元总个数.

#include<stdio.h>
#include<string.h>
int main()
{
    char lstring [100];
    int n;
    printf("please enter a string:(within 100 characters):");
    scanf("%s",lstring);
    n=strlen(lstring);
    int a;char string[n];
    for(a=0;a<n;a++)
        string[a]=lstring[a];
        string[n]='\0';
    char gnirts[n+1];
    for(a=0;a<n;a++)
        gnirts[n-1-a]=string[a];
        gnirts[n]='\0';
    printf("%s\n",string);
    printf("%s",gnirts);
    return 0; 
}

(5) 计量输入句子中的字符数,单词数,行数.

#include<stdio.h>
#include<ctype.h>/*import function: isalpha() to judge a letter*/
int main()
{
    char ch=0;
    int n_ch=0,n_line=1,n_word=0,bool=0;
    printf("please enter a sentence(\"|\" to stop):");
    while((ch=getchar())!='|')
    {
        if (!isalpha(ch))
            bool=0;
        if (isalpha(ch))
        {
            n_ch++;
        }
        if (isalpha(ch)&&bool==0)
        {
            n_word++;
            bool=1;
        }
        if (ch=='\n')
            n_line++;
    }
    printf("%d characters,%d words,%d lines in total",n_ch,n_word,n_line);
    return 0;
}

(6)求比输入数字小的所有素数.(很多内嵌循环,写得比较臃肿).

如果把第18行的break;去掉,那么代码的运行效率会低很多.

#include<stdio.h>
int main()
{
    int s,s0,num,a;
    printf("please enter a positive number:");
    while(scanf("%d",&s)==1)
    {
        if(s>0)
        {
            printf("%d is a positive number,the sushu less than %d is :",s,s);
            for(s0=1,num=0;s0<=s;s0++)
            {
                for(a=2;a<s0;a++)
                {
                    if(s0%a==0)
                        {
                            num++;
                            break;
                        }
                }
                if(num==0)
                    printf("%d,",s0);
                num=0;
            }
        }
        else 
            printf("not a positive number\nplease entert another positive number:");
    }
    printf("error!");
    return0;
}

(7)猜数字.第10行的判断条件可以避免在扫描字符时误将'\n'扫描到程序中.此代码判断输入'\n'时,执行第10行while循环之外的部分.

#include<stdio.h>
int main()
{
    printf("please think about a number between 1-100\n");
    float sml=1,big=100;
    char ch;
    while(big-sml>1)
    {
        printf("%.3f-%.3f?(print(y/n)):",sml,(big+sml)/2);
        while((ch=getchar())!='\n')
        {   if(ch=='y')
                big=(big+sml)/2;     
            if(ch=='n')
                sml=(big+sml)/2;
        }
    }
    printf("%d",(int)big);
    return 0;
}

(8)10进制与二进制相互转化.

十进制转换为二进制时,输入最大十进制数字a为1023,是因为十进制的1023用二进制表示为1111111111,此数为小于int型变量的最大值(2147483647)的最大二进制数值,而十进制的1024用二进制表示为10000000000,大于int型变量的最大值.所以1023为一个转折点.

当然,程序员也可以修改b的类型为long,long long,甚至可以把所有变量都修改为long long类型,可以扩大程序的转换范围.不过,到底有没有必要转换a,x的类型还需要程序员自己判断(直觉告诉我不需要).我这里就不啰嗦了.

#include<stdio.h>
#include<math.h>
int cal1(int x);
int cal2(int x);
int main()
{
    int a,y;
    printf("please enter 1 to convert 10 to 2 and enter 2 to convert2 to 10.(char to quit)");
    while(scanf("%d",&y)==1)
    {
        if (y==1)
        {
            printf("please enter a number between 0 to 1023 :");
            scanf("%d",&a);
            if(a<0||a>1023)
                printf("this number is out of limit!\n");
            else
                printf("the number you want is %d\n",cal1(a));                
        }
        else if (y==2)
        {
            printf("please enter a number between 0 to 1111111111:");
            scanf("%d",&a);
            if(a<0||a>1111111111)
                printf("this number is out of limit!\n");
            else
                {
                    int test=a;
                    while(test>0)
                    {   if(test%10>=0&&test%10<=2)
                            {
                                test-=test%10;
                                test/=10;
                            }
                        else
                        {
                            printf("this is not a Binary digits\n");
                            goto retry;
                        }
                    }
                    printf("the number you want is %d\n",cal2(a));
                }
        }
        else
            printf("wrong number\n");
        retry:printf("enter 1 to convert 10 to 2 and 2 to convert2 to 10.(char to quit)\n");
    }
    printf("code completed\n");
    return 0;
}

int cal1(int a)
{
    int x,n=0,b=0;
    
    while(a>=1)
    {
        x=a%2;
        b+=x*pow(10,n);
        n++;
        a-=x;
        a/=2;
    }
    return b;
}

int cal2(int a)
{
    int x,b=0,n=0;
    while(a>=1)
    {
        x=a%10;
        b+=x*pow(2,n);
        n++;
        a-=x;
        a/=10;
    }
    return b;
}

(8.1)使用位运算快速实现10-2进制转换

#include<stdio.h>
#include<limits.h>
int main()
{
    unsigned long a;
    scanf("%ld",&a);
    int n = CHAR_BIT*sizeof(long);
    char b[n];
    b[n]='\0';
    for(int i=n-1;i>=0;i--)
    {
        b[i]=(a&0x01)+'0';
        a >>= 1;
    }
    puts(b);
    return 0;
}

(8.2)十进制数字以二进制数字字符串形式输出

半个小时8行哈哈哈哈

void show_ten_in_char_bi(int a)
{
    static  int n=0;
    n++;
    if(a)
    {   
        show_ten_in_char_bi(a>>1);
        if((--n%4)==0)
            putchar(' ');
        putchar((a&0x1)+'0');
    }
}

(9) 将输入数字进行排序

程序分为三部分.

第一部分(4-8行):将输入放到数组input[]中

第二部分(9-12行):根据输入数字的数量定义output[]并初始化.这里将每个值都初始化为float类型的最小值.这样初始化是为了保证每一个进入output的input值都能保留在其中,防止被其中随机的大值排出在外.

第三部分(13-28)行:将input[]中的每一个值经过比较大小后放入output[]中.

第一个for为执行每一个input[]中的值,
第二个for为将每一个执行的input[i]值与output[]中的值进行比较,决定它放在哪里.else中的for是将output中的靠后面的值读区相邻的靠前的数值,if为将input[i]的值储存在相应的output[]中.

第三个for是输出output[]的值.

#include<stdio.h>
int main()
{
    printf("please enter the number to rank(within 100 numbers)(char to quit):");
    float input [100];
    int n=0;
    while(scanf("%f",&input[n])==1)
        n++;
    float output[n+1];
    int i;
    for(i=0;i<=n;i++)
        output[i]=-3.40282e+038; /* this is the minimize of float */
    int ii,x;
    for(i=0;i<n;i++)
    {
        for(ii=0;ii<n+1;ii++)
        {
            if(input[i]<output[ii])
                continue;
            else
            {
                for(x=n;x>ii;x--)
                    output[x]=output[x-1];
                output[ii]=input[i];
                break;
            }
        }
    }
    for(i=0;i<n;i++)
        printf("%f\n",output[i]);
    return 0;
}

(10)读取输入的字符串,并消去其中的某个字符,并记录此字符的数量.

子函数s_fgets的一种情况下的作用是使用fgets()函数读取字符串,并删除'\n'(如果有(即输入的非'\n'字符个数小于n-1,(n来自fgets(char * ch,int n)))).另一种情况下的作用是清除缓存区中的其他字符,这只有当输入屏幕的字符串的数量>=n-1时才会执行.

这两种情况组成所有情况.

#include<stdio.h>
#include<string.h>
#define CONTENT 100
#define WHICHCHAR ' '
char * s_fgets(char ch[],int n);
char * s_fgets(char ch[],int n)
{
    char * bol=fgets(ch,n,stdin);
    // printf("fgets complete");
    char * find;
    if(bol)
    {
        find=strchr(ch,'\n');
        if(find)
            *find='\0';
        else
            while(getchar()!='\n')
                continue;
        // printf("s_gets complete");
    }
    return bol;
}
int main()
{
    char ipt[CONTENT];
    int i,count;
    while(s_fgets(ipt,CONTENT)&&*ipt)
    {
        // printf("into while");
        for(count=0,i=0;i<CONTENT&&*(ipt+i)!='\0';i++)
            {
                while(*(ipt+i+count)==WHICHCHAR)
                    count++;
                *(ipt+i)=*(ipt+i+count);
            }
        printf("the quanity of '%c' is %d\n",count,WHICHCHAR);
        puts(ipt);
        printf("complete.'\\n' to quit.\n");
    }
    printf("quit succfuly");
}

(11)倒序输出字符串

8,21,22行使用函数strcat()函数,但必须要定义一个指向char的指针.

18,19行使用sprintf()函数,但必须要确定第一个参数的指向地址.

16行通过比较两个数组首元素地址的差值直接赋值,较为简便.

三种方法都可以实现相同的功能.

#include<stdio.h>
#include<string.h>
int main()
{
    char ipt[100];
    char opt[100];
    int i=0;
    char ch;char * temp=ch;
    char * p=ipt;
    fgets(ipt,100,stdin);
    while(*(++p))
    continue;
    while(*(--p))
    {

        // *(opt+i++)=*p;

        // i++;
        // sprintf(opt+i,"%c",*p);

        *temp=*p;
        strcat(opt,temp);


        // putchar(*p);
        // puts(opt);
    }


}

(12)四则运算

本人热衷于嵌套循环。发现四则运算中的括号中的内容完全可以作为新的运算,所以采用嵌套循环,即默认输入的字符串自带一个括号。

主要流程:

  1. 从字符串中提取数字和运算符。

数字使用读取while循环判断是否为数字(isalnum()(from:ctype.h))或者小数点,提取字符转化为新字符串,使用atof转化为float类型数据,放入堆栈中。

运算符直接读取:

  • 如果是四则运算符:若在站内已有至少一个运算符时与前一个运算符比较优先级:如果前一个运算符优先级高于或等于当前栈顶运算符,则pop出前一个运算符,并pop出数字栈中的两个栈顶数字,进行运算后push入栈。(为了能够识别负数,所以需要在数字栈和运算符栈元素都为1时,将数字栈的栈底加入数字0,这样才能使运算符栈内的唯一运算符作用于两个数字。)
  • 如果是'('则继续读取,直至读到逻辑上对应个')'。因为可能出现括号中有括号的情况,所以不能使用strchr或者strrchr,应该记录读取到的'('和‘)'数量。当数量匹配时,才可以作为新的嵌套循环的输入值。

当所有元素提取完成之后,我们再来看一下数字栈和运算符栈中剩余的内容:

运算符栈中存在至少为0,之多为输入字符串中运算符总数。无论是如何,栈内顶部运算符的优先级肯定要高于底下一个运算符的优先级。

数字栈中数字的数量为运算符栈运算符的数量(或者加一,即括号内是负数)

         2、从尾到头把数字做运算。

从运算符栈顶pop出运算符,从数字栈中pop两个数字,进行相应运算。结束后将运算结果重新push入数字栈。依次循环直至运算符栈元素数量为0,数字栈元素数量为1.

总结:

我们从头来捋一下流程。首先,所有的表达式都能找到对应个括号。所以,括号内的内容都可以作为嵌套循环的输入。这样,我们就可以无需考虑括号了。

接着,我们可以把所有的运算顺序看成单个小单元,每个小单元内的运算顺序为从左到右,小单元与小单元直接的运算顺序为从右到左(对应栈的从顶到底)。在上面流程1中我们在读取字符串,读取到运算符时自动判断优先级,即自动判断当前小单元内有无从左到右的运算,如果没有,则不进行运算,小单元内只有对应的一个运算符和一个运算符后面的数字。如果有,则直接从左到右运算,也是只留下对应的一个运算符和一个运算符后面的数字。

这样下来,读取完整个字符串之后,我们顺便让每个小单元只对应一个运算符和一个数字。之后进行流程2,从右向左运算。

缺点:

1由于是嵌套循环,空间复杂度为n^x(x为维度,即括号嵌套的数量),所以不能计算括号中出现很多括号,中出现很多括号的情况,这样会占用大量的内存空间。

这种让数字pop出,计算,再push入栈的操作个人认为会比较浪费时间。可以采用变量储存结果,并拿去进行接下来的运算,或者直接改变栈内数字的值,即只pop不push

#include<stdio.h>
#include<ctype.h>
#include"stack_4cal.h"

float cal(char input[]) ;

int main()
{
    char input[50]="(-1)+1.1*(0.2*(2-1)/1)";
    printf("%.3f,",cal(input));
}

float cal(char input[])//解释
{
    STACK Number={NULL,0};
    STACK Operator={NULL,0};
    char ch=0;;
    
    int i=0;
    ch=input[i];
    while(ch!='\0')
    {
        if(isalnum(ch)||ch=='.')//解释
        {
            char chi[5]={0};
            int ii=0;
            while(isalnum(ch)||ch=='.')
            {
                chi[ii]=ch;
                ii++;
                i++;
                ch=input[i];
            }
            i--;
            ITEM a={atof(chi),'\0',0};//解释
            PushToStack(a,&Number);
        }
        else 
        {   
            int class_=0;
            if(ch=='(')
            {
                int kuohaojudg1=1;
                int kuohaojudg2=0;
                char kuohaoch[30]={0};
                int ii=0;
                for(ii=0;;ii++)
                {
                    if(input[i+ii+1]=='(')
                    {
                        kuohaoch[ii]=input[i+ii+1];
                        kuohaojudg1++;
                    }
                    else if(input[i+ii+1]==')')
                    {   
                        kuohaojudg2++;
                        if(kuohaojudg1==kuohaojudg2)
                            break;
                        kuohaoch[ii]=input[i+ii+1];
                    }
                    else
                        kuohaoch[ii]=input[i+ii+1];
                }
                kuohaoch[ii]='\0';
                kuohaoch[ii+1]='\0';
                ITEM tempp={0,'\0',0};
                tempp.num=cal(kuohaoch);
                PushToStack(tempp,&Number);
                i=i+ii+2;
                ch=input[i];
            }
            if(ch=='+'||ch=='-')
                class_=0;
            else if(ch=='*'||ch=='/')
                class_=1;

            ITEM a={0,ch,class_};
            PushToStack(a,&Operator);
            
            while(Operator.num>=2&&Operator.top->item.class_<=Operator.top->next->item.class_)
            {   
                if(a.ch=='\0')
                {
                    ITEM temp={0,'\0',0};
                    PopFromStack(&temp,&Operator);
                    continue;
                }
                ITEM temptop={0,'\0',0};
                ITEM tempnext={0,'\0',0};
                PopFromStack(&temptop,&Operator);
                PopFromStack(&tempnext,&Operator);
                PushToStack(temptop,&Operator);
                ITEM temptopi={0,'\0',0};
                ITEM tempnexti={0,'\0',0};
                PopFromStack(&temptopi,&Number);
                PopFromStack(&tempnexti,&Number);
                float iii=0;
                switch(tempnext.ch)
                {
                    case '+':
                        iii=tempnexti.num+temptopi.num;
                        temptopi.num=iii;
                        PushToStack(temptopi,&Number);
                        break;
                    case '-':
                        iii=tempnexti.num-temptopi.num;
                        temptopi.num=iii;
                        PushToStack(temptopi,&Number);
                        break;
                    case '*':
                        iii=tempnexti.num*temptopi.num;
                        temptopi.num=iii;
                        PushToStack(temptopi,&Number);
                        break;
                    case '/':
                        iii=tempnexti.num/temptopi.num;
                        temptopi.num=iii;
                        PushToStack(temptopi,&Number);
                        break;

                }
            }
        }
        i++;
        ch=input[i];
    }
    while(!StackIsEmpty(&Operator))//解释
    {
        if(Number.num==1)
        {
            ITEM top={0,'\0',0};
            PopFromStack(&top,&Number);
            ITEM end={0,'\0',0};
            end.num=0;
            PushToStack(end,&Number);
            PushToStack(top,&Number);
        }
        ITEM temptop={0,'\0',0};
        PopFromStack(&temptop,&Operator);
        ITEM temptopi={0,'\0',0};
        ITEM tempnexti={0,'\0',0};
        PopFromStack(&temptopi,&Number);
        PopFromStack(&tempnexti,&Number);
        switch(temptop.ch)
        {
            float iii;
            case '+':
                iii=tempnexti.num+temptopi.num;
                temptopi.num=iii;
                PushToStack(temptopi,&Number);
                break;
            case '-':
                iii=tempnexti.num-temptopi.num;
                temptopi.num=iii;
                PushToStack(temptopi,&Number);
                break;
            case '*':
                iii=tempnexti.num*temptopi.num;
                temptopi.num=iii;
                PushToStack(temptopi,&Number);
                break;
            case '/':
                iii=tempnexti.num/temptopi.num;
                temptopi.num=iii;
                PushToStack(temptopi,&Number);
                break;
        }
    }
  

    // printf("%d\n",Number.top->item.num);
    float temp=Number.top->item.num;
    
    DeleteStack(&Number);
    DeleteStack(&Operator);
    return temp;


}

#ifndef __STACK_4CAL_H__
#define __STACK_4CAL_H__
#define MAXNUMBER 10
#include<stdbool.h>
#include<string.h>
#include<stdlib.h>
#include<stdio.h>



typedef struct item
{
    float num;
    char ch;
    int class_;
}ITEM;

typedef struct node
{
    ITEM item;
    struct node * next;
}NODE;

typedef struct stack
{
    NODE * top;
    unsigned int num;
}STACK;

bool StackIsEmpty(STACK * Stack)
{
    if(Stack->num==0)
        return true;
    else 
        return false;
}

bool StackIsFull(STACK * Stack)
{
    if(Stack->num>=MAXNUMBER)
        return true;
    else 
        return false;
}

bool PushToStack(ITEM a,STACK * Stack)
{
    if(StackIsFull(Stack))
    {
        fprintf(stderr,"failed to Push Item to Satck:Stack is full");;
        return false;
    }
    Stack->num++;
    NODE * pnode=(NODE * )malloc(sizeof(NODE));
    if(pnode==NULL)
    {
        fprintf(stderr,"failed to push Item toStack:malloc error");
        return false;
    }
    else
    pnode->item=a;
    pnode->next=Stack->top;
    Stack->top=pnode;
    return true;
}

bool PopFromStack(ITEM * Item,STACK * Stack)
{
    if(StackIsEmpty(Stack))
    {
        // fprintf(stderr,"failed to pop Item from Satck:Stack is empty");
        return false;
    }
    else 
    {
        *Item=Stack->top->item;
        NODE * tempnext=Stack->top->next;
        free(Stack->top);
        Stack->num--;
        Stack->top=tempnext;
        return true;
    }
}

bool DeleteStack(STACK * Stack)
{
    ITEM tempitem;
    while(PopFromStack(&tempitem,Stack))
        continue;
    if(Stack->num==0)
        return true;
    else 
        return false;
    
}





#endif

(13)三元组法对稀疏矩阵实现存储,输出,转置。

目录:

|-Sparse_Matrix

        |-Inc

                |-sparse_matrix_10.h

                |-sparse_matrix_3.h

        |-Src

                |-sparse_matrix_10.c

                |-sparse_matrix_3.c

        |-README.md

sparse_matrix_3.h:

//an ADT of sparse matrix 
#ifndef __SPARSE_MATRIX_3_H_
#define __SPARSE_MATRIX_3_H_
#include<stdio.h>
#include<assert.h>
#include<stdlib.h>
#include<stdbool.h>
#include<string.h>


#define MAXNUMBER 50

typedef struct node
{
    unsigned int column;
    unsigned int row;
    int a;     
} NODE;

typedef struct
{
    unsigned int num_row;
    unsigned int num_column;   
    unsigned int num;
    NODE data[MAXNUMBER];

} SPARSE_MATRIX;



int cmp_row(const void * first,const void * second)
{
    if(((NODE *)first)->row>((NODE *)second)->row)
        return 1;
    if(((NODE *)first)->row==((NODE *)second)->row)
        return 0;
    if(((NODE *)first)->row<((NODE *)second)->row)
        return -1;
    return 0;
}
int cmp_column(const void * first,const void * second)
{
    if(((NODE *)first)->column>((NODE *)second)->column)
        return 1;
    if(((NODE *)first)->column==((NODE *)second)->column)
        return 0;
    if(((NODE *)first)->column<((NODE *)second)->column)
        return -1;
    return 0;
}


void CreatMatrix(SPARSE_MATRIX *test,unsigned int row ,unsigned int column, int matrix [row][column])
{
    test->num_row = row;
    test->num_column = column;
    test->num = 0;

    for(int i = 0; i < row; i++)
    {
        for(int j = 0; j < column; j++)
        {
            if(matrix[i][j] != 0)
            {
                test->data[test->num].row = i+1;
                test->data[test->num].column = j+1;
                test->data[test->num].a = matrix[i][j];
                test->num++;
            }
        }
    }
}
void ShowMatrix(SPARSE_MATRIX * test)
{
    unsigned int cur_num=0;
    unsigned int cur_column;
    unsigned int cur_row=1;
    while(cur_row<=test->num_row)
    {
        if(cur_row==test->data[cur_num].row)
        {
            cur_column=1;
            while(cur_column<=test->num_column)
            {
                if(cur_num==test->num)//to avoid segsion fault cause by unseged array 
                {
                    while(cur_column<=test->num_column)
                    {
                        printf("0\t");
                        cur_column++;
                    }
                    break;
                }

                if(cur_row==test->data[cur_num].row&&cur_column==test->data[cur_num].column)
                {
                    printf("%d\t",test->data[cur_num].a);
                    cur_num++;
                }
                else if(cur_row==test->data[cur_num].row&&cur_column<test->data[cur_num].column)
                    printf("0\t");
                else if(cur_row==test->data[cur_num].row&&cur_column>test->data[cur_num].column)
                    assert(0);
                else if(test->data[cur_num].row>cur_row)
                    printf("0\t");
                else 
                    assert(0);
                cur_column++;
            }
        }
        else if(cur_row<test->data[cur_num].row)
        {
            for(int i=1;i<=test->num_column;i++)
                printf("0\t");
        }
        else if(cur_row>test->data[cur_num].row)
            assert(0);
        else
            assert(0);

        putchar('\n');
        cur_row++;

    }
    putchar('\n');
}
void Transpose_Matrix(SPARSE_MATRIX *test)
{
    unsigned int temp=test->num_column;
    test->num_column=test->num_row;
    test->num_row=temp;
    for(int i=0;i<test->num;i++)
    {
        int temp;
        temp=test->data[i].column;
        test->data[i].column=test->data[i].row;
        test->data[i].row=temp;
    }
    qsort(test->data,test->num,sizeof(NODE),cmp_row);
    unsigned int i=0;
    unsigned int sort_num;
    while(i<test->num)
    {
        sort_num=0;
        while(i<test->num-1&&test->data[i].row==test->data[i+1].row)
        {  
            i++;
            sort_num++;
        }
        if(i>=test->num-1)
        {
            qsort(test->data+i-sort_num,sort_num+1,sizeof(NODE),cmp_column);
            break;
        }
        else 
        {
            qsort(test->data+i-sort_num,sort_num+1,sizeof(NODE),cmp_column);
            i++;
        }

    }
}






#endif

sparse_matrix_10.h:

//an ADT of sparse matrix 
#ifndef __SPARSE_MATRIX_10_H_
#define __SPARSE_MATRIX_10_H_
#define MAXNUMBER 200
#include<stdio.h>
#include<assert.h>
#include<stdlib.h>
#include<stdbool.h>
#include<string.h>

typedef struct node
{
    unsigned int column;
    unsigned int row;
    int num  ;
    struct node * column_next;
    struct node * row_next;
}NODE;
typedef struct sparse_matrix
{
    NODE * set;
    unsigned int num_row;
    unsigned int num_column;
}SPARSE_MATRIX;



bool AddToMatrix(SPARSE_MATRIX * matrix,unsigned int row ,unsigned int column,int a)
{
    NODE * pnode_column=matrix->set;
    for(unsigned int i=0;i<column+1;i++)
        pnode_column=pnode_column->column_next;

    NODE * pnode_row=matrix->set;
    for(unsigned int i=0;i<row+1;i++)
        pnode_row=pnode_row->row_next;

    NODE * pnode_target={0};

    
    while(1)//to find the correct position(row) for node_target
    {
        if(pnode_column->row_next==NULL)
        {
            pnode_target=malloc(sizeof(NODE));
            pnode_column->row_next=pnode_target;
            pnode_column->row_next->num=a;
            pnode_column->row_next->column=column;
            pnode_column->row_next->row=row;
            pnode_column->row_next->row_next=NULL;
            break;
        }
        else if(pnode_column->row_next->row<row)
        {
            pnode_column=pnode_column->row_next;
            continue;
        }
        else if(pnode_column->row_next->row==row)
        {
            pnode_column->row_next->num=a;
            break;
        }
        else if(pnode_column->row_next->row>row)
        {
            NODE * temp_pnode=pnode_column->row_next;
            pnode_target=malloc(sizeof(NODE));
            pnode_column->row_next=pnode_target;
            pnode_column->row_next->num=a;
            pnode_column->row_next->column=column;
            pnode_column->row_next->row=row;
            pnode_column->row_next->row_next=temp_pnode;
            break;
        }
    }


    if(pnode_row->column_next==NULL)
    {
        pnode_row->column_next=pnode_target;
        pnode_target->column_next=NULL;
    }
    else
        while(1)
        {
            if(pnode_row->column_next==NULL)
            {
                pnode_row->column_next=pnode_target;
                pnode_target->column_next=NULL;
                break;
            }
            else if(pnode_row->column_next->column<column)
            {
                pnode_row=pnode_row->column_next;
                continue;
            }
            else if(pnode_row->column_next->column==column)
            {
                if(pnode_row->column_next!=pnode_target)
                {
                    fprintf(stderr,"signicifant logical error:multiply declaration of pnode_traget.");
                    assert(0);
                }
                break;
            }
            else if(pnode_row->column_next->column>column)
            {
                int temp_column=pnode_row->column_next->column;
                NODE * temp_pnode=pnode_row->column_next;
                pnode_row->column_next=pnode_target;
                pnode_target->column_next=temp_pnode;
                break;
            }
        }
    return true;

}


bool CreatMatrix(SPARSE_MATRIX * Sparse_matrix ,unsigned int row ,unsigned int column, int matrix [row][column])
{
    NODE * Set=malloc(sizeof(NODE));
    if(Set==NULL)
    {
        fprintf(stderr,"failed to creat matrix:malloc error");
        return NULL;
    }
    Sparse_matrix->set=Set;
    Sparse_matrix->num_column=column+1;
    Sparse_matrix->num_row=row+1;

    NODE * Set_column[column+1];
    for(unsigned int i=1;i<=column;i++)
    {
        Set_column[i]=malloc(sizeof(NODE));
        if(Set_column[i]==NULL)
        {
            fprintf(stderr,"failed to creat matrix:malloc error");
            return false;
        }
        Set_column[i]->row=0;
        Set_column[i]->column=i;
    }
    for(unsigned int i=1;i<=column;i++)
    {
        if(i==column)
            Set_column[i]->column_next=NULL;
        else 
            Set_column[i]->column_next=Set_column[i+1];
        Set_column[i]->row_next=NULL;
    }
    Sparse_matrix->set->column_next=Set_column[1];
    

    NODE * Set_row[row+1];
    for(unsigned int i=1;i<=row;i++)
    {
        Set_row[i]=malloc(sizeof(NODE));
        if(Set_row[i]==NULL)
        {
            fprintf(stderr,"failed to creat matrix:malloc error");
            return false;
        }
        Set_row[i]->row=i;
        Set_row[i]->column=0;
    }
    for(unsigned int i=1;i<=row;i++)
    {
        if(i==row)
            Set_row[i]->row_next=NULL;
        else 
            Set_row[i]->row_next=Set_row[i+1];
        Set_row[i]->column_next=NULL;
    }
    Sparse_matrix->set->row_next=Set_row[1];



    for(unsigned int i=0;i<row;i++)
    {
        for(unsigned int ii=0;ii<column;ii++)
        {
            if(matrix[i][ii])
                AddToMatrix(Sparse_matrix,i,ii,matrix[i][ii]);
        }
    }
    return true;
}



void ShowMatrix(SPARSE_MATRIX * matrix)
{
    NODE * node_column;
    NODE * node_row=matrix->set->row_next;
    unsigned int current_num;
    while(node_row!=NULL)
    {
        node_column=node_row->column_next;
        current_num=1;
        while(current_num<matrix->num_column)
        {
            if(node_column==NULL)
            {
                printf("0\t");
            }
            else 
            {
                if((node_column->column+1)==current_num)
                {
                    printf("%d\t",node_column->num);
                    node_column=node_column->column_next;
                }
                else if((node_column->column+1)>current_num)
                    printf("0\t");
                else if((node_column->column+1)<current_num)
                    printf("0\t");

            }
            current_num++;
        }
        
        node_row=node_row->row_next;
        putchar('\n');
            
    }
}

bool FreeMatrix(SPARSE_MATRIX * matrix)
{
    NODE * pcolumn;
    NODE * prow=matrix->set;
    NODE * temp_column;
    NODE * temp_row;
    do
    {
        temp_row=prow;
        prow=prow->row_next;
        do
        {
            temp_column=temp_row;
            temp_row=temp_row->column_next;
            printf("%d ",temp_column->num);
            free(temp_column);
        } while (temp_row!=NULL);
        putchar('\n');


    } while (prow!=NULL);

    return true;
    
    

}








#endif

sparse_matrix_3.c:

#include"sparse_matrix_3.h"
int main()
{
    SPARSE_MATRIX test;
    CreatMatrix(&test,7,5,(int[7][5]){{0,1,0,2,0},{3,0,4,0,5},{0,6,0,7,0},{8,0,9,0,10},{0,11,0,12,0},{13,0,14,0,15},{0,16,0,17,0}});
    ShowMatrix(&test);
    Transpose_Matrix(&test);
    ShowMatrix(&test);
   

    

}

sparse_matrix_10.c:

#include"sparse_matrix_10.h"
int main()
{
    SPARSE_MATRIX test;
    CreatMatrix(&test,7,5,(int[7][5]){{0,1,0,2,0},{3,0,4,0,5},{0,6,0,7,0},{8,0,9,0,10},{0,11,0,12,0},{13,0,14,0,15},{0,16,0,17,0}});
    ShowMatrix(&test);
    FreeMatrix(&test);
}

readme:

使用三元组创建、修改、转置、输出稀疏矩阵。

转置过程为修改行列值,使用qsort()先对行进行快速排序,再对列进行快速排序

使用稀疏矩阵创建、修改、输出稀疏矩阵。

创建过程为先读取行列数,创建十字链表的表头,并置空。读取所有非0数据,按照依次读取输入输入的复合字面量的每行中的每列的数据,按照先贴在列表头,再与行表头衔接的方式添加至十字链表中。

修改的过程为读取要修改的数据和所在的位置后,先在十字链表中定位到修改的位置,若所在位置原本存在节点,则直接修改节点数据;若不存在节点,则按照先在列链表中从链表头向后移动,直至找到节点与节点之间或者节点与NULL之间的位置,创建新节点连接上下左右四个方向的两个节点或者NULL之间。

输出过程为按照行的方式从表头像后读取,并且在输出中填充0.

下图123为debug过程中工作区变量的变化,可以看到矩阵实现了转置。

图4显示了稀疏矩阵实际存储在内存中的形式,可以看到是使用十字链表形式。

​​​​​​​

 

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值