zoukankan      html  css  js  c++  java
  • 数据结构顺序表——线性表实现

    数据结构作业,做代码保存

    #include<string.h>
    #include<ctype.h>
    #include<malloc.h> // malloc()等
    #include<limits.h> // INT_MAX等
    #include<stdio.h> // EOF(=^Z或F6),NULL
    #include<stdlib.h> // atoi()
    #include<io.h> // eof()
    #include<math.h> // floor(),ceil(),abs()
    #include<process.h> // exit()
    #include<iostream> // cout,cin
    using namespace std;
    // 函数结果状态代码
    #define TRUE 1
    #define FALSE 0
    #define OK 1
    #define ERROR 0
    #define INFEASIBLE -1
    // #define OVERFLOW -2 因为在math.h中已定义OVERFLOW的值为3,故去掉此行
    typedef int Status; // Status是函数的类型,其值是函数结果状态代码,如OK等
    typedef int Boolean; // Boolean是布尔类型,其值是TRUE或FALSE
    typedef int ElemType;
    //线性表的动态分配顺序存储结构
    #define LIST_INIT_SIZE 10 // 线性表存储空间的初始分配量
    #define LISTINCREMENT 2 // 线性表存储空间的分配增量
    struct SqList
    {
        ElemType *elem; // 存储空间基址
        int length; // 当前长度
        int listsize; // 当前分配的存储容量(以sizeof(ElemType)为单位)
    };
    //顺序表示的线性表的基本操作(12个)
    Status InitList(SqList &L) /// 初始化顺序表
    {
        // 操作结果:构造一个空的顺序线性表
        L.elem=(ElemType*)malloc(LIST_INIT_SIZE*sizeof(ElemType));
        if(!L.elem) exit(OVERFLOW); // 存储分配失败
        L.length=0; // 空表长度为0
        L.listsize=LIST_INIT_SIZE; // 初始存储容量
        *L.elem=0;///初始化了第一个元素
        return OK;
    }
    
    Status DestroyList(SqList &L)///销毁顺序表
    {
        // 初始条件:顺序线性表L已存在。操作结果:销毁顺序线性表L
        free(L.elem);
        L.elem=NULL;
        L.length=0;
        L.listsize=0;
        return OK;
    }
    
    Status ClearList(SqList &L)///将顺序表重置为空表
    {
        // 初始条件:顺序线性表L已存在。操作结果:将L重置为空表
        L.length=0;
        return OK;
    }
    
    Status ListEmpty(SqList L)///判断是否为空表
    {
        // 初始条件:顺序线性表L已存在。操作结果:若L为空表,则返回TRUE,否则返回FALSE
        return L.length?FALSE:TRUE;
    }
    
    int ListLength(SqList L)///返回线性表元素个数
    {
        // 初始条件:顺序线性表L已存在。操作结果:返回L中数据元素个数
        return L.length;
    }
    
    Status GetElem(SqList L,int i,ElemType &e)///获取线性表中第i个元素
    {
        // 初始条件:顺序线性表L已存在,1≤i≤ListLength(L)
        // 操作结果:用e返回L中第i个数据元素的值
        if(i<1||i>L.length)
            exit(ERROR);
        e=*(L.elem+i-1);
        return OK;
    }
    
    int LocateElem(SqList L,ElemType e,Status(*compare)(ElemType,ElemType))///按compare()位序返回元素
    {
        // 初始条件:顺序线性表L已存在,compare()是数据元素判定函数(满足为1,否则为0)
        // 操作结果:返回L中第1个与e满足关系compare()的数据元素的位序。
        //           若这样的数据元素不存在,则返回值为0。
        int i=1;
        ElemType *p=L.elem;
        while(i<=L.length&&!(*compare)(*p++,e))++i;
        if(i<=L.length)return i;
        else return 0;
    }
    
    Status PriorElem(SqList L,ElemType cur_e,ElemType &pre_e)///返回cur_e元素的前驱元素
    {
        // 初始条件:顺序线性表L已存在
        // 操作结果:若cur_e是L的数据元素,且不是第一个,则用pre_e返回它的前驱,
        //           否则操作失败,pre_e无定义
        int i=2;
        ElemType *p=L.elem+1;
        while(i<=L.length&&*p!=cur_e)
        {
            p++;
            i++;
        }
        if(i>L.length)
            return INFEASIBLE;
        else
        {
            pre_e=*--p;
            return OK;
        }
    }
    
    Status NextElem(SqList L,ElemType cur_e,ElemType &next_e)///返回cur_e元素的后继元素
    {
        // 初始条件:顺序线性表L已存在
        // 操作结果:若cur_e是L的数据元素,且不是最后一个,则用next_e返回它的后继,
        //           否则操作失败,next_e无定义
        int i=1;
        ElemType *p=L.elem;
        while(i<=L.length&&*p!=cur_e)
        {
            p++;
            i++;
        }
        if(i>L.length-1)
            return INFEASIBLE;
        else
        {
            next_e=*++p;
            return OK;
        }
    }
    
    Status ListInsert(SqList &L,int i,ElemType e) ///插入元素
    {
        // 初始条件:顺序线性表L已存在,1≤i≤ListLength(L)+1
        // 操作结果:在L中第i个位置之前插入新的数据元素e,L的长度加1
        if(i<1||i>L.length+1)return ERROR;
        if(L.length>=L.listsize)
        {
            ElemType *newbase=(ElemType *)realloc(L.elem,(L.listsize+LISTINCREMENT)*sizeof(ElemType));
            if(!newbase)exit(OVERFLOW);
            L.elem=newbase;
            L.listsize+=LISTINCREMENT;
        }
        ElemType *q=&(L.elem[i-1]);
        for(ElemType *p=&(L.elem[L.length-1]); p>=q; --p) *(p+1)=*p;
        *q=e;
        L.length++;
        return OK;
    }
    
    Status ListDelete(SqList &L,int i,ElemType &e) ///删除元素
    {
        // 初始条件:顺序线性表L已存在,1≤i≤ListLength(L)
        // 操作结果:删除L的第i个数据元素,并用e返回其值,L的长度减1
        if((i<1)||(i>L.length))return ERROR;
        ElemType *p=&(L.elem[i-1]);
        e=*p;
        ElemType *q=L.elem+L.length-1;
        for(++p; p<=q; ++p) *(p-1)=*p;
        L.length--;
        return OK;
    }
    
    Status ListTraverse(SqList L,void(*vi)(ElemType&))///依次对L的每个数据元素调用函数vi()
    {
        // 初始条件:顺序线性表L已存在
        // 操作结果:依次对L的每个数据元素调用函数vi()。一旦vi()失败,则操作失败
        //           vi()的形参 加'&',表明可通过调用vi()改变元素的值
        ElemType *p;
        int i;
        p=L.elem;
        for(i=1; i<=L.length; i++)
            vi(*p++);
        cout<<endl;//相当于c语言里面的printf("
    ")
        return OK;
    }
    
    
    ///*==========================================================================================*/
    
    
    
    void InsertAscend(SqList &L,ElemType e)///按非严格递增插入元素
    {
        // 初始条件:按非降序排列的顺序线性表L已存在
        // 操作结果:在L中按非降序插入新的数据元素e,L的长度加1
        int j;
        for(j=0; j<L.length; j++)
            if(e<=*(L.elem+j))
                break;
        ListInsert(L,j+1,e);
    
    }
    
    void InsertDescend(SqList &L,ElemType e)///按非严格递减插入元素
    {
        // 初始条件:按非升序排列的顺序线性表L已存在
        // 操作结果:在L中按非升序插入新的数据元素e,L的长度加1
        int j;
        for(j=0; j<L.length; j++)
            if(e>=*(L.elem+j))
                break;
        ListInsert(L,j+1,e);
    }
    
    Status HeadInsert(SqList &L,ElemType e)///在顺序表L 头部 插入新元素
    {
        // 初始条件:顺序线性表L已存在。操作结果:在L的头部插入新的数据元素e,L的长度加1
        ElemType *p,*q,*newbase;
        if(L.length>=L.listsize)
        {
            if(!(newbase=(ElemType *)realloc(L.elem,(L.listsize+LISTINCREMENT)*sizeof(ElemType))))
                exit(OVERFLOW);
            L.elem=newbase;
            L.listsize+=LISTINCREMENT;
        }
        q=L.elem;
        for(p=L.elem+L.length-1; p>=q; --p)
            *(p+1)=*p;
        *q=e;
        L.length++;
        return OK;
    }
    
    Status EndInsert(SqList &L,ElemType e)///在顺序表L 尾部 插入新元素
    {
        // 初始条件:顺序线性表L已存在。操作结果:在L的尾部插入新的数据元素e,L的长度加1。
        ElemType *p,*q,*newbase;
        if(L.length>=L.listsize)
        {
            if(!(newbase=(ElemType *)realloc(L.elem,(L.listsize+LISTINCREMENT)*sizeof(ElemType))))
                exit(OVERFLOW);
            L.elem=newbase;
            L.listsize+=LISTINCREMENT;
        }
        q=L.elem+L.length;
        *q=e;
        L.length++;
        return OK;
    }
    
    Status DeleteFirst(SqList &L,ElemType &e)///删除顺序表中第一个元素
    {
        // 初始条件:顺序线性表L已存在,且有不少于1个元素
        // 操作结果:删除L的第一个数据元素,并由e返回其值,L的长度减1
        ElemType *p,*q;
        if(!L.length) return ERROR;
        p=L.elem;///首地址也是第一个元素的的地址,用指针存储
        e=*p;///e作为一个元素,应是指针p指向的元素
        q=L.elem+L.length-1;
        for(++p; p<=q; ++p) *(p-1)=*p;
        L.length--;
        return OK;
    }
    
    Status DeleteTail(SqList &L,ElemType &e)///删除顺序表中最后一个元素
    {
        // 初始条件:顺序线性表L已存在,且有不少于1个元素
        // 操作结果:删除L的最后一个数据元素,并用e返回其值,L的长度减1
        ElemType *p;
        if(!L.length) // 空表
            return ERROR;
        p=L.elem+L.length-1; // 最后一个数据元素的位置
        e=*p; // 被删除元素的值赋给e
        L.length--; // 表长减1
        return OK;
    }
    
    Status DeleteElem(SqList &L,ElemType e)
    {
        // 删除表中值为e的元素,并返回TRUE;如无此元素,则返回FALSE
        ElemType *p;
        int flag=0;
        for(p=L.elem; p<=L.elem+L.length-1; p++)
        {
            if(*p==e)
            {
                flag=1;
                ElemType *q=L.elem+L.length-1;
                ElemType *P=p;
                for(++P; P<=q; ++P) *(P-1)=*P;
                L.length--;
                p--;
            }
        }
        return flag?TRUE:FALSE;
    }
    
    Status ReplaceElem(SqList L,int i,ElemType e)
    {
        // 用e取代表L中第i个元素的值
        if(i<1||i>L.length)
            exit(ERROR);
        *(L.elem+i-1)=e;
        return OK;
    }
    
    Status CreatAscend(SqList &L,int n)///非严格递增顺序建表
    {
        // 按非降序建立n个元素的线性表
        int i,j;
        ElemType e;
        InitList(L);
        printf("请输入%d个元素:
    ",n);
        cin>>e;
        ListInsert(L,1,e); // 在空表中插入第1个元素
        for(i=1; i<n; i++)
        {
            cin>>e;
            for(j=0; j<L.length; j++)
                if(e<=*(L.elem+j))
                    break;
            ListInsert(L,j+1,e); // 插于表中
        }
        return TRUE;
    }
    
    Status CreatDescend(SqList &L,int n)///非严格递减顺序建表
    {
        // 按非升序建立n个元素的线性表
        int i,j;
        ElemType e;
        InitList(L);
        printf("请输入%d个元素:
    ",n);
        cin>>e;
        ListInsert(L,1,e); // 在空表中插入第1个元素
        for(i=1; i<n; i++)
        {
            cin>>e;
            for(j=0; j<L.length; j++)
                if(e>=*(L.elem+j))
                    break;
            ListInsert(L,j+1,e); // 插于表中
        }
        return TRUE;
    }
    
    
    ///==========================================================================
    Status comp(ElemType c1,ElemType c2) /// 数据元素判定函数(平方关系)
    {
        if(c1==c2*c2)
            return TRUE;
        else
            return FALSE;
    }
    
    void visit(ElemType &c) /// ListTraverse()调用的函数(类型要一致)
    {
        cout<<c<<' ';
    }
    
    void dbl(ElemType &c) /// ListTraverse()调用的另一函数(元素值加倍)
    {
        c*=2;
    }
    void UNION(SqList &La,SqList Lb)///去重联合顺序表
    {
        ElemType e;
        for(int i=1; i<=Lb.length; i++)
        {
            GetElem(Lb,i,e);
            if(!LocateElem(La,e,comp))
            {
                ListInsert(La,1+La.length,e);///因为这里我用了线性表的长度直接判断,因此不能像书上一样做自增操作,应该直接+1比较保险
            }
        }
    }
    void MergeList(SqList La,SqList Lb,SqList &Lc)///非递减排列顺序表
    {
        InitList(Lc);
        int i=1,j=1,k=0;
        int La_len=ListLength(La),Lb_len=ListLength(Lb);
        ElemType ai,bj;
        while((i<=La_len)&&(j<=Lb_len))
        {
            GetElem(La,i,ai);
            GetElem(Lb,j,bj);
            if(ai<=bj)
            {
                ListInsert(Lc,++k,ai);
                ++i;
            }
            else
            {
                ListInsert(Lc,++k,bj);
                ++j;
            }
        }
        while(i<=La_len)
        {
            GetElem(La,i++,ai);
            ListInsert(Lc,++k,ai);
        }
        while(j<=Lb_len)
        {
            GetElem(Lb,j++,bj);
            ListInsert(Lc,++k,bj);
        }
    }
    int main()
    {
        int num=1;
        SqList La,Lb,Lc;
        InitList(La);
        printf("表La中初始元素:");
        for(int i=1; i<=7; i++)
        {
            ListInsert(La,num++,i);
            printf("%d%c",i,i==7?'
    ':' ');
        }
        InitList(Lb);
        num=1;
        printf("表Lb中初始元素:");
        for(int i=3; i<=10; i++)
        {
            ListInsert(Lb,num++,i);
            printf("%d%c",i,i==10?'
    ':' ');
        }
        UNION(La,Lb);
        printf("合并后表La中元素:");
        ElemType e;
        for(int i=1; i<=La.length; i++)
        {
            printf("%d%c",La.elem[i-1],i==La.length?'
    ':' ');
        }
        printf("
    ");
        InitList(La),InitList(Lb),InitList(Lc);
        num=1;
        printf("表La中初始元素:");
        for(int i=1; i<=10; i+=2)
        {
            ListInsert(La,num++,i);
            printf("%d%c",i,i==9?'
    ':' ');
        }
        num=1;
        printf("表Lb中初始元素:");
        for(int i=2; i<=10; i+=2)
        {
            ListInsert(Lb,num++,i);
            printf("%d%c",i,i==10?'
    ':' ');
        }
        MergeList(La,Lb,Lc);
        printf("表Lc归并后有%d个元素
    ",Lc.length);
        printf("归并后Lc中元素:");
        for(int i=1; i<=Lc.length; i++)
            printf("%d%c",Lc.elem[i-1],i==Lc.length?'
    ':' ');
    
    ///=================================================================================
        char g='1';
        SqList L;
        ElemType e0;
        Status i;
        int j,k;
        i=InitList(L);
        printf("初始化L后:L.elem=%u L.length=%d L.listsize=%d
    ",*L.elem,L.length,L.listsize);
        //在L的表头依次插入1~5,并且在屏幕上依次输出5个元素
        for(i=1; i<=5; i++)
        {
            HeadInsert(L,i);
            printf("%d%c",i,i==5?'
    ':' ');
        }
    
        printf("L.elem=%u L.length=%d L.listsize=%d
    ",*L.elem,L.length,L.listsize);
        i=ListEmpty(L);
        printf("L是否空:i=%d(1:是 0:否)
    ",i);
        i=ClearList(L);
        printf("清空L后:L.elem=%u L.length=%d L.listsize=%d
    ",*L.elem,L.length,L.listsize);
        i=ListEmpty(L);
        printf("L是否空:i=%d(1:是 0:否)
    ",i);
        //在L的表尾依次插入1~10,并且在屏幕上依次输出10个元素
        for(i=1; i<=10; i++)
        {
            EndInsert(L,i);
            printf("%d%c",i,i==10?'
    ':' ');
        }
    
        printf("L.elem=%u L.length=%d L.listsize=%d
    ",*L.elem,L.length,L.listsize);
        //在L的表头插入0,并且在屏幕上依次输出11个元素
        HeadInsert(L,0);
        for(int i=1; i<=L.length; i++)
        {
            GetElem(L,i,e);
            printf("%d%c",e,i==L.length?'
    ':' ');
        }
    
        printf("L.elem=%u(有可能改变) L.length=%d(改变) L.listsize=%d(改变)
    ",*L.elem,L.length,L.listsize);
        // 取线性表中的第5个元素,并且在屏幕上输出
        GetElem(L,5,e);
        printf("%d
    ",e);
    
        for(j=3; j<=4; j++)
        {
            k=LocateElem(L,j,comp);
            if(k)
                printf("第%d个元素的值为%d的平方
    ",k,j);
            else
                printf("没有值为%d的平方的元素
    ",j);
        }
        for(j=1; j<=2; j++) // 测试头两个数据
        {
            GetElem(L,j,e0); // 把第j个数据赋给e0
            i=PriorElem(L,e0,e); // 求e0的前驱
            if(i==INFEASIBLE)
                printf("元素%d无前驱
    ",e0);
            else
                printf("元素%d的前驱为:%d
    ",e0,e);
        }
        for(j=ListLength(L)-1; j<=ListLength(L); j++) // 最后两个数据
        {
            GetElem(L,j,e0); // 把第j个数据赋给e0
            i=NextElem(L,e0,e); // 求e0的后继
            if(i==INFEASIBLE)
                printf("元素%d无后继
    ",e0);
            else
                printf("元素%d的后继为:%d
    ",e0,e);
        }
        k=ListLength(L); // k为表长
        for(j=k+1; j>=k; j--)
        {
            i=ListDelete(L,j,e); // 删除第j个数据
            if(i==ERROR)
                printf("删除第%d个数据失败
    ",j);
            else
                printf("删除的元素值为:%d
    ",e);
        }
        printf("依次输出L的元素:");
        ListTraverse(L,visit); // 依次对元素调用visit(),输出元素的值
        printf("L的元素值加倍后:");
        ListTraverse(L,dbl); // 依次对元素调用dbl(),元素值乘2
        ListTraverse(L,visit);
        DestroyList(L);
        printf("销毁L后:L.elem=%u L.length=%d L.listsize=%d
    ",L.elem,L.length,L.listsize);
        while(g!='0')scanf("%c",&g);
    }
    
  • 相关阅读:
    WampServer软件
    ASP.NET Core中返回 json 数据首字母大小写问题
    区块链的入门与应用(1)
    阿里云oss 的坑==》 路径有区分大小写
    uni-app 学习笔记 小于号问题
    uni-app 学习笔记-引用外部js并调用
    net core 简单读取json配置文件
    net core 3 使用 autofac
    js 获取对应的url参数
    postman 跟restsharp 模拟请求http
  • 原文地址:https://www.cnblogs.com/kuronekonano/p/11794318.html
Copyright © 2011-2022 走看看