数据结构顺序表——线性表实现

来源:互联网 发布:matlab 雅可比矩阵 编辑:程序博客网 时间:2024/06/12 00:23

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

#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,cinusing 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或FALSEtypedef 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("\n")    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",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",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?'\n':' ');    }    InitList(Lb);    num=1;    printf("表Lb中初始元素:");    for(int i=3; i<=10; i++)    {        ListInsert(Lb,num++,i);        printf("%d%c",i,i==10?'\n':' ');    }    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?'\n':' ');    }    printf("\n");    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?'\n':' ');    }    num=1;    printf("表Lb中初始元素:");    for(int i=2; i<=10; i+=2)    {        ListInsert(Lb,num++,i);        printf("%d%c",i,i==10?'\n':' ');    }    MergeList(La,Lb,Lc);    printf("表Lc归并后有%d个元素\n",Lc.length);    printf("归并后Lc中元素:");    for(int i=1; i<=Lc.length; i++)        printf("%d%c",Lc.elem[i-1],i==Lc.length?'\n':' ');///=================================================================================    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\n",*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?'\n':' ');    }    printf("L.elem=%u L.length=%d L.listsize=%d\n",*L.elem,L.length,L.listsize);    i=ListEmpty(L);    printf("L是否空:i=%d(1:是 0:否)\n",i);    i=ClearList(L);    printf("清空L后:L.elem=%u L.length=%d L.listsize=%d\n",*L.elem,L.length,L.listsize);    i=ListEmpty(L);    printf("L是否空:i=%d(1:是 0:否)\n",i);    //在L的表尾依次插入1~10,并且在屏幕上依次输出10个元素    for(i=1; i<=10; i++)    {        EndInsert(L,i);        printf("%d%c",i,i==10?'\n':' ');    }    printf("L.elem=%u L.length=%d L.listsize=%d\n",*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?'\n':' ');    }    printf("L.elem=%u(有可能改变) L.length=%d(改变) L.listsize=%d(改变)\n",*L.elem,L.length,L.listsize);    // 取线性表中的第5个元素,并且在屏幕上输出    GetElem(L,5,e);    printf("%d\n",e);    for(j=3; j<=4; j++)    {        k=LocateElem(L,j,comp);        if(k)            printf("第%d个元素的值为%d的平方\n",k,j);        else            printf("没有值为%d的平方的元素\n",j);    }    for(j=1; j<=2; j++) // 测试头两个数据    {        GetElem(L,j,e0); // 把第j个数据赋给e0        i=PriorElem(L,e0,e); // 求e0的前驱        if(i==INFEASIBLE)            printf("元素%d无前驱\n",e0);        else            printf("元素%d的前驱为:%d\n",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无后继\n",e0);        else            printf("元素%d的后继为:%d\n",e0,e);    }    k=ListLength(L); // k为表长    for(j=k+1; j>=k; j--)    {        i=ListDelete(L,j,e); // 删除第j个数据        if(i==ERROR)            printf("删除第%d个数据失败\n",j);        else            printf("删除的元素值为:%d\n",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\n",L.elem,L.length,L.listsize);    while(g!='0')scanf("%c",&g);}