• 数据结构之线性表


    1:线性表:谈到线性表,可以联想到26个英语字母,他们从逻辑上组成一个有序的序列就是线性表,另外,线性表也可以是班上的成绩登记表,其中包括学号,姓名,还有各科的成绩等等。对于一个非空的线性表,注意:各个元素的长度是相同的:

    2:线性表的基本运算包括 a:初始化 b计算表长 c获取结点 d查找结点e插入结点 f删除结点

    在这里,我们讨论了线性表的逻辑结构和数据运算,还没有对其存储结构进行讨论,在计算机中,线性表采用二种方法来存储,一种是顺序存储,另一种是链式存储,顺序存储的线性表叫顺序表,链式存储的表叫链表

    A:顺序结构表

    因为顺序结构表在存储方式上是连续的,因此,只要知道该顺序表的首地址,以及每个元素占用的存储长度,就可以计算出任何一个数据元素的位置(也就是可以计算出任何衣蛾结点的位置),这种思想是我们操作顺序表结构的基本思想Loc(Ai) = Loc(a1)+(i-1)*c;

    操作顺序表的步骤

    1:准备数据:也就是准备顺序表中需要用到的变量以及数据结构等等

    示例代码:

    #define MAXLEN 100 //定义顺序表的最大长度
    
    typedef struct
    {
            char key[10];//定义节点关键字
            char name[20];
            int age;
    }DATA;//定义结点类型
    
    typedef struct
    {
            DATA ListData[MAXLEN+1];//保存顺序表的结构数组
            int ListLen;//顺序表已保存的节点数
    
    }SLType;
           
    

     其实这里我们定义了一个顺序表,这里可以记录100个学生的基本情况,其中顺序表的数据元素类型是DATA,以及顺序表的数据结构SLType。在数据结构SLType中,ListLen为顺序表已存在的结点数量,也就是当前顺序表的长度,ListData是一个数组,用来存放各结点数据

    2:初始化一个顺序表

    在使用顺序表之前,我们要创建一个空的顺序表,也就是初始化顺序表,这里程序中只需要设置顺序表的结点数量ListLen等于0即可。在后面添加的元素将从顺序表的第一个位置存储

    void SLInit(SLType *SL)
    {
            SL->ListLen =0;//初始化顺序表
    
    }
    

    需要注意的是,我们这里没有清空顺序表,如果原来顺序表中有数据,也会被覆盖,但是不会影响chaozuo

    3:计算顺序表的长度

    示例代码:

    int SLLength(SLType *SL)
    {
            return(SL->ListLen);//返回顺序表的结构
    
    }
    

    计算顺序表的结构也就是

     插入结点:在线性表L中插入一个新的结点,使得结点后面的编号依次加一,这是,插入新的结点后,线性表的长度将变为N+1,插入结点的难点在于随后的每个数据都要进行移动计算量比较大

    int SLInsert(SLType*SL,int n,DATA data)
    {
            int i;
            if(SL ->ListLen >= MAXLEN)//顺序表的结点数量已经超过最大数量
            {
                    printf("顺序表已满,不能插入结点");
                    return 0;
    
            }
    
            if(n<1 ||n>SL->ListLen-1)//插入的结点不正确
            {
                    printf("插入元素序号错误,不能插入元素");
                    return 0;
            }
    
            for(i = SL->ListLen;i>=n;i--)//将表中的数据向后移动一位
            {
                    SL->ListData[i+1] = SL->ListData[i];
    
            }
            SL->ListData[n] = data;//插入结点
            SL ->ListLen++;//顺序表的结点数量增加1
    
            return 1;//插入成功表示返回1
    
    }
    

     这里程序要先判断顺序表的结点数量是否超过最大的数量,以及插入结点的序号是否正确,但条件满足的时候,便将顺序表中的数据向后移动,同时插入结点,并更新ListLen

    追加结点:

    int SLAdd(SLType*SL,DATA data)
    {
            if(SL->Listen>=MAXLEN)
            {
                    printf("顺序表已满,不能在添加结点");
                    return 0;
            }
            SL->ListData[++SL->ListLen] = data;
            return 1;
    
    
    }
    

     追加结点并不是基本的数据结构操作,但是由于算法比较简单,这里单独给出代码

    删除结点:

    int SLDelete(SLType*SL,int n)
    {
            int i;
            if(n<1||n>SL->ListLen+1)
            {
                    printf("删除结点序号错误,不能删除结点");
                    return 0;
            }
            for(i = n;i<ListLen;i++)//将顺序表中的数据向前移动即可
            {
                    SL->ListData[i] = SL->ListData[i+1];
            }
            SL->ListLen --;
            return 1;//成功的话,返回值为1
    }
    

     这里首先判断待删除的及结点序号是否正确,如果正确,开始移动数据,并更新结点数量ListLen

    查找结点

    查找结点,顾名思义就是查找值为x的结点,并返回该结点在线性表中的位置,如果在线性表中没有找到结点为x的结点则返回一个错误标志,根据x类型的不同,查找的方式可以分为按序号查找结点或按关键字查找结点

    按照序号查找结点:

    DATA*SLFindByNum(SLType*SL,int n)
    {
            if(n<1||n>SL->ListLen+1)
            {
                    printf("结点序号错误");
                    return NULL;
            }
    
            return &(SL->ListData[n]);
    }
    

     对于一个顺序表,序号就是数据元素在数组中的位置,也就是数组元素的下标标号,按照序号查找结点是顺序表查找的最常用的方法,这是因为顺序表存储本身就是一个数组

    按照关键字查找结点:

    int SLFindByCont(SLType*sl,char *key)
    {
            int i;
            for(i= 1;i<SL->ListLen;i++)
            {
                    if(strcmp(sl->Data[i].key,key)==0)
                    return i;
            }
    
            return 0;
    }
    

    这是一个比较常见的按照关键字进行查找的例子,我们可以看作是学生的学号为关键字

    显示所有结点:

    int SLAll(STLType*SL)
    {
            int i;
            for(i=1;i<SL->ListLen;i++)
            {
                    printf("(%s,%S,%D)N",Sl->ListData[i].key,SL->ListData[i].name,SL->ListData[i].age);
            return 0;
            }
    }
    

     显示所有结点的数据并不是数据结构的基本运算,因为他可以是简单的逐个引用结点来实现,这里单独列出一个函数,用来操作显示所有结点

     冒泡法排序:

    //冒泡法排序 从小到大依次排序
    #include<stdio.h>
    #define Len 10
    
    //冒泡法的基本算法
    void BubbleSort(int *a)
    {
        int i,j,temp;
        for(i = 0;i<Len-1;i++)
            for(j = Len-1;j>i;j--)//从后面开始往前面比较这样比较容易理解
            {
                if(a[j-1]>a[j])
                {
                    temp = a[j-1];
                    a[j-1] = a[j];
                    a[j] = temp;
                }
            }
    }
    int main()
    {
        int a[Len],i;
        printf("please input a[10]
    ");
        for(i = 0;i<Len;i++)
            scanf("%d",&a[i]);
        
        BubbleSort(a);
    
        printf("the order is:
    ");
        
        for(i = 0;i< Len;i++)
            printf("%3d",a[i]);
        printf("
    ");
        
        return 0;
    }
    View Code

    顺序表操作

    #include<stdio.h>
    #include<string.h>
    
    #define MAXLEN 100
    typedef struct
    {    char key[10];    
        char name[20];
        int age;
    }DATA;
    
    typedef struct 
    {    
        DATA ListData[MAXLEN];    
        int ListLen;
    }SLType;
    //初始化顺序表
    void SLInit(SLType *SL)
    {    
        SL->ListLen = 0;
    }
    //计算顺序表的长度
    int SLLength(SLType *SL)
    {    
        return (SL->ListLen);
    }
    
    //插入结点
    int SLInsert(SLType*SL,int n,DATA data)
    {    
        int i;
        if(SL->ListLen >=MAXLEN)    
        {        
            printf("结点已经满了");    
            return 0;    
        }    
        if(n<0||n>MAXLEN)
        {    
            printf("插入的结点有误");    
            return 0;
        }    
        for(i = SL->ListLen;i>n;i--)    
        {        
            SL->ListData[i+1] = SL->ListData[i];    
        }    
        SL->ListData[n] = data;    
        SL->ListLen ++;    return 1;
    }
    
    //增加结点
    int SLAdd(SLType *SL,DATA data)
    {    
        if(SL->ListLen >MAXLEN)
        {        
            printf("增加失败,结点已经满了");
            return 0;    
        }    
        SL->ListLen ++;    
        SL->ListData[SL->ListLen] = data;    
        return 1;
    }
    
    //删除结点
    int SLDelete(SLType*SL,int n)
    {    
        int i;
        if(n<0||n>SL->ListLen+1)    
        {        
            printf("删除结点失败");    
            return 0;    
        }    
        for(i = n;i<SL->ListLen;i++)
        {        
            SL->ListData[i] = SL->ListData[i+1];
        }
        SL->ListLen--;
        return 1
    ;}
    //按序号查找
    DATA *SLFindByNum(SLType*SL,int n)
    {    
        if(n<0||n>SL->ListLen)
        {        
            printf("查找结点失败");        
            return NULL;
        }    
        return &(SL->ListData[n]);}
    
    //按关键字查找
    int SLFindByCont(SLType*SL,char *key)
    {    
        int i;    
        for(i=0;i<SL->ListLen;i++)    
        {    
            if(strcmp(SL->ListData[i].key,key)==0)    
                return i;    
        }
        return 0;
    }
    
    //显示所有结点
    int SLAll(SLType*SL)
    {    
        int i;
        for(i = 0;i<SL->ListLen;i++)
        {        
            printf("%s,%s,%d",SL->ListData[i].key,SL->ListData[i].name,SL->ListData[i].age);
        }    
        return 0;
    }
    int main()
    {    
        int i;
        SLType SL;
        DATA data;
        DATA *pdata;
        char key[10];
        printf("顺序表演示
    ");
        SLInit(&SL);//初始化顺序表    
        printf("顺序表初始化完成
    ");
        
        do    
        {    
            printf("输入添加的结点(学号,姓名,年龄)");        
            fflush(stdin);//清空输入缓存区    
            scanf("%s%s%d",&data.key,&data.name,&data.age);    
            if(data.age)        
            {            
                if(!SLAdd(&SL,data))//添加结点失败        
                {            
                    break;    
                }        
            }        
            else//年龄为0,退出死循环    
            {        
                break;    
            }    
        }while(1);    
        printf("
    顺序表中的结点顺序
    ");    
        SLAll(&SL);//显示所有结点数据
        fflush(stdin);
        printf("
    需要取出的结点
    ");    
        scanf("%d",&i);    
        pdata = SLFindByNum(&SL,i);
        if(pdata)    
        {    
            printf("第%d个结点为:(%s,%s,%d)",i,pdata->key,pdata->name,pdata->age);        
        }
        fflush(stdin);
        printf("
    要查找的结点的关键字
    ");
        scanf("%s",key);
        i = SLFindByCont(&SL,key);
        pdata = SLFindByNum(&SL,i);
        if(pdata)    
        {        
            printf("第%d个结点为:(%s,%s,%d)
    ",i,pdata->key,pdata->name,pdata->age);    
        //    getch();
        return 0;    
        }    
        return 0;
    }
    View Code

    版权所有,转载请注明链接地址:

  • 相关阅读:
    SEO优化之外链的末日来临
    【九章算法免费讲座第一期】转专业找CS工作的“打狗棒法”
    关于Windows下程序运行的说明
    bootstrap学习——javascript插件篇
    使用Linq 查询数据 构建对象 select new{}
    多级联动系列——ajax调用XML实现三级联动
    C语言指针实现字符串的反转
    分布式事物的原理图
    计算机网络之物理层笔记
    reveal end of document
  • 原文地址:https://www.cnblogs.com/fengdashen/p/3444903.html
Copyright © 2020-2023  润新知