线性表的顺序存储与实现

来源:互联网 发布:tensorflow linux 推荐 编辑:程序博客网 时间:2024/05/01 12:23

线性表的顺序存储与实现

  线性表的顺序存储是指在内存中用一组地址连续的存储单元一次存储线性表的各元素,用这种存储形式存储的线性表称为顺序表。
  
  之前没看书的时候还以为线性表的顺序存储指的是结构体数组,后来看了下书发现是一个含有数组的结构体,其实我个人觉得结构体数组比较好用,含有数组的结构体和数组的区别不大,只是多了对数组信息的存储。
  
  下面先介绍顺序表吧(以存储的数据为整数为例 typedef int ElemType):

定义顺序表的类型

#define LIST_INIT_SIZE 100  //线性表存储空间的初始分配量#define LISTINCREMENT 10    //线性表存储空间的分配增量typedef int ElemType;typedef struct{    ElemType *elem;     //存储空间基址    int length;     //当前长度    int listsize;   //当前分配的存储容量(以sizeof(ElemType)为单位)}SqList;

1、线性表的初始化(InitList_Sq)

Status InitList_Sq(SqList *L){    L->elem = (int*)malloc(LIST_INIT_SIZE * sizeof(ElemType));    if(!L->elem)        return ERROR;    L->length = 0;    L->listsize = LIST_INIT_SIZE;    return OK;}

2、线性表的查找操作(LocateElem_Sq)

int LocateElem_Sq(SqList L, ElemType e){    /*顺序表L已经存在,返回L中第1个与e相等的数据元素的位序*/    /*若这样的数据元素不存在,则返回值为0*/    ElemType *p;    int i = 1;      //i的初值为第1个元素的位序    p = L.elem;     //p的初值为第1个元素的存储位置    while(i <= L.length && (*p++) != e)     /*并非所有元素都可以使用(*p++) != e判断是否相等*/        ++i;    if(i <= L.length)        return i;    else        return 0;}

3、线性表的插入操作

Status ListInsert_Sq(SqList *L, int i, ElemType e){    /*顺序表L已存在,当 1<=i<=ListLength(L)+1 时,在L中第i个位置之前插入新的数据    元素e,L的长度增1*/    ElemType *newbase;    int j;    if(i < 1 || i > L->length+1)    //判断i值是否合法        return ERROR;    if(L->length >= L->listsize){   //当前存储空间已满,增加分配        newbase = (ElemType*)realloc((*L).elem,            ((*L).listsize+LISTINCREMENT)*sizeof(ElemType));        if(!newbase)            return ERROR;        L->elem = newbase;        L->listsize = L->listsize + LISTINCREMENT;    }    for(j = (L->length)-1; j >= i-1; j--)        L->elem[j+1] = L->elem[j];    L->elem[i-1] = e;    ++L->length;    return OK;}

4、线性表的删除操作

ElemType ListDelete_Sq(SqList *L, int i){    /*删除顺序表L中的第i个(1<=i<=ListLength(L))数据元素,并用e返回其值,L的长度减1*/    int j;    ElemType e;    if(i < 1 || i > L->length)      //判断i值是否合法        return ERROR;    e = L->elem[i-1];    for(j = i; j < L->length; j++)        L->elem[j-1] = L->elem[j];    L->length--;    return e;}

5、两个集合的并集

void Union_Sq(SqList *La, SqList *Lb)   //集合的合并操作{    /*将所有在线性表Lb中但不在La中的数据元素依次插入到La中*/    int e;    int La_len, Lb_len;    int i;    La_len = La->length,    Lb_len = Lb->length;    for(i = 1; i <= Lb_len; i++){        e = Lb->elem[i-1];        if(!LocateElem_Sq(*La,e))            ListInsert_Sq(La, ++La_len, e);    }       }

6、两个有序表的合并

void MergeList_Sq(SqList La, SqList Lb, SqList *Lc){    /*已知线性表La和Lb中的数据元素按值非递减排列*/    /*归并La和Lb得到新的线性表Lc,Lc的数据元素也按值非递减排列*/    int i = 0, j = 0, k = 1;    int ai,bj;    InitList_Sq(Lc);    while(i <= La.length-1 && j <= Lb.length-1){        ai = La.elem[i];        bj = Lb.elem[j];        if(ai <= bj){            ListInsert_Sq(Lc,k,ai);            i++;            k++;        }        else{            ListInsert_Sq(Lc,k,bj);            j++;            k++;        }    }    while(i <= La.length-1){        ai = La.elem[i];        ListInsert_Sq(Lc, k, ai);        i++;        k++;    }    while(j <= Lb.length-1){        bj = Lb.elem[j];        ListInsert_Sq(Lc, k, bj);        j++;        k++;    }}

全部代码

#include <stdio.h>#include <stdlib.h>#define TRUE 1#define FALSE 0#define OK 1#define ERROR 0#define INFEASIBLE -1#define OVERFLOW -2typedef int Status;typedef int Boolean;#define LIST_INIT_SIZE 100  //线性表存储空间的初始分配量#define LISTINCREMENT 10    //线性表存储空间的分配增量typedef int ElemType;typedef struct{    ElemType *elem;     //存储空间基址    int length;     //当前长度    int listsize;   //当前分配的存储容量(以sizeof(ElemType)为单位)}SqList;Status InitList_Sq(SqList *L);int LocateElem_Sq(SqList L,ElemType e);Status ListInsert_Sq(SqList *L,int i,ElemType e);ElemType ListDelete_Sq(SqList *L, int i);void Union_Sq(SqList *La, SqList *Lb);void MergeList_Sq(SqList La, SqList Lb, SqList *Lc);void Print_Sq(SqList L);int main(void){    SqList La;    int i,j,k,n;    InitList_Sq(&La);    printf("请输入元素个数:");    scanf("%d",&n);    printf("请输入元素: ");    for(i = 0; i < n; i++){        scanf("%d",&j);        if(!ListInsert_Sq(&La, La.length+1, j)){            printf("空间分配失败!\n");            exit(OVERFLOW);        }    }    printf("输入的元素为: ");    Print_Sq(La);    printf("请输入要插入的值及其插入到第几个元素之前: ");    scanf("%d%d",&i,&j);    ListInsert_Sq(&La, j, i);    Print_Sq(La);    printf("请输入要删除第几个元素:");    scanf("%d",&i);    k = ListDelete_Sq(&La, i);    printf("删除的元素的值为 %d\n", k);    Print_Sq(La);    SqList Lb, Lc;    InitList_Sq(&Lb);    printf("请再输入一组元素: ");    for(i = 0; i < n; i++){        scanf("%d",&j);        if(!ListInsert_Sq(&Lb, Lb.length+1, j)){            printf("空间分配失败!\n");            exit(OVERFLOW);        }    }    printf("输入的元素为: ");    Print_Sq(Lb);    printf("将第二组有且第一组没有的元素合并到第一组: ");    Union_Sq(&La, &Lb);    Print_Sq(La);    free(La.elem);    free(Lb.elem);    InitList_Sq(&La);    InitList_Sq(&Lb);    InitList_Sq(&Lc);    printf("请再输入两组非降序元素:\n");    printf("第一组: ");    for(i = 0; i < n; i++){        scanf("%d",&j);        if(!ListInsert_Sq(&La, La.length+1, j)){            printf("空间分配失败!\n");            exit(OVERFLOW);        }    }    printf("第二组: ");    for(i = 0; i < n; i++){        scanf("%d",&j);        if(!ListInsert_Sq(&Lb, Lb.length+1, j)){            printf("空间分配失败!\n");            exit(OVERFLOW);        }    }    MergeList_Sq(La, Lb, &Lc);    printf("按序合并为: ");    Print_Sq(Lc);    return 0;}Status InitList_Sq(SqList *L){    L->elem = (int*)malloc(LIST_INIT_SIZE * sizeof(ElemType));    if(!L->elem)        return ERROR;    L->length = 0;    L->listsize = LIST_INIT_SIZE;    return OK;}int LocateElem_Sq(SqList L, ElemType e){    /*顺序表L已经存在,返回L中第1个与e相等的数据元素的位序*/    /*若这样的数据元素不存在,则返回值为0*/    ElemType *p;    int i = 1;      //i的初值为第1个元素的位序    p = L.elem;     //p的初值为第1个元素的存储位置    while(i <= L.length && (*p++) != e)     /*并非所有元素都可以使用(*p++) != e判断是否相等*/        ++i;    if(i <= L.length)        return i;    else        return 0;}Status ListInsert_Sq(SqList *L, int i, ElemType e){    /*顺序表L已存在,当 1<=i<=ListLength(L)+1 时,在L中第i个位置之前插入新的数据    元素e,L的长度增1*/    ElemType *newbase;    int j;    if(i < 1 || i > L->length+1)    //判断i值是否合法        return ERROR;    if(L->length >= L->listsize){   //当前存储空间已满,增加分配        newbase = (ElemType*)realloc((*L).elem,            ((*L).listsize+LISTINCREMENT)*sizeof(ElemType));        if(!newbase)            return ERROR;        L->elem = newbase;        L->listsize = L->listsize + LISTINCREMENT;    }    for(j = (L->length)-1; j >= i-1; j--)        L->elem[j+1] = L->elem[j];    L->elem[i-1] = e;    ++L->length;    return OK;}ElemType ListDelete_Sq(SqList *L, int i){    /*删除顺序表L中的第i个(1<=i<=ListLength(L))数据元素,并用e返回其值,L的长度减1*/    int j;    ElemType e;    if(i < 1 || i > L->length)      //判断i值是否合法        return ERROR;    e = L->elem[i-1];    for(j = i; j < L->length; j++)        L->elem[j-1] = L->elem[j];    L->length--;    return e;}void Union_Sq(SqList *La, SqList *Lb)   //集合的合并操作{    /*将所有在线性表Lb中但不在La中的数据元素依次插入到La中*/    int e;    int La_len, Lb_len;    int i;    La_len = La->length,    Lb_len = Lb->length;    for(i = 1; i <= Lb_len; i++){        e = Lb->elem[i-1];        if(!LocateElem_Sq(*La,e))            ListInsert_Sq(La, ++La_len, e);    }       }void MergeList_Sq(SqList La, SqList Lb, SqList *Lc){    /*已知线性表La和Lb中的数据元素按值非递减排列*/    /*归并La和Lb得到新的线性表Lc,Lc的数据元素也按值非递减排列*/    int i = 0, j = 0, k = 1;    int ai,bj;    InitList_Sq(Lc);    while(i <= La.length-1 && j <= Lb.length-1){        ai = La.elem[i];        bj = Lb.elem[j];        if(ai <= bj){            ListInsert_Sq(Lc,k,ai);            i++;            k++;        }        else{            ListInsert_Sq(Lc,k,bj);            j++;            k++;        }    }    while(i <= La.length-1){        ai = La.elem[i];        ListInsert_Sq(Lc, k, ai);        i++;        k++;    }    while(j <= Lb.length-1){        bj = Lb.elem[j];        ListInsert_Sq(Lc, k, bj);        j++;        k++;    }}void Print_Sq(SqList L){    int i;    for(i = 0; i < L.length; i++)        printf("%d ", L.elem[i]);    printf("\n");}

运行结果
运行结果

总结
 其实顺序表就是一个记录长度,并且是动态分配空间的数组,个人觉得结构体数组以及链表的作用会更大一些。

更新(改善了交互性及容错性)

全部代码

#include <stdio.h>#include <stdlib.h>#define TRUE 1#define FALSE 0#define OK 1#define ERROR 0#define INFEASIBLE -1#define OVERFLOW -2typedef int Status;typedef int Boolean;#define LIST_INIT_SIZE 100  //线性表存储空间的初始分配量#define LISTINCREMENT 10    //线性表存储空间的分配增量typedef int ElemType;typedef struct{    ElemType *elem;     //存储空间基址    int length;     //当前长度    int listsize;   //当前分配的存储容量(以sizeof(ElemType)为单位)}SqList;Status InitList_Sq(SqList *L);int LocateElem_Sq(SqList L, ElemType e);Status Find_Sq(SqList L, int i, ElemType *e);Status ListInsert_Sq(SqList *L, int i, ElemType e);ElemType ListDelete_Sq(SqList *L, int i, ElemType *e);void Union_Sq(SqList *La, SqList *Lb);void MergeList_Sq(SqList La, SqList Lb, SqList *Lc);void Print_Sq(SqList L);void Print_Hyphen(int n);int main(void){    SqList La,Lb,Lc;    int end = 0,opt = 0;    int i,j,k,n;    Print_Hyphen(5);    printf("线性表的顺序存储与实现示例");    Print_Hyphen(5);    printf("\n");    InitList_Sq(&La);    printf("请输入元素个数:");    scanf("%d",&n);    printf("请输入元素: ");    for(i = 0; i < n; i++){        scanf("%d",&j);        if(!ListInsert_Sq(&La, La.length+1, j)){            printf("空间分配失败!\n");            exit(OVERFLOW);        }    }    printf("输入的元素为: ");    Print_Sq(La);    while(!end){        Print_Hyphen(15); printf("\n");        Print_Hyphen(5); printf("功能列表"); Print_Hyphen(5);        printf("\n");        printf("1、输入序号查找元素\n2、输入元素查找序号\n3、插入元素\n");        printf("4、删除元素\n5、求两组元素的并集\n6、按序合并两个非递减序列\n");        printf("7、退出演示\n");        Print_Hyphen(15); printf("\n");        printf("输入要使用的功能的序号: ");        scanf("%d",&opt);        Print_Hyphen(15);        printf("\n");        switch(opt){            case 1:                int find;                printf("请输入要查找元素的序号: ");                scanf("%d",&find);                if(Find_Sq(La, find, &k))                    printf("元素为:%d\n", k);                else                    printf("输入的序号不合法!");                break;            case 2:                ElemType findLoc;                printf("请输入要获得序号的元素: ");                scanf("%d",&findLoc);                if(LocateElem_Sq(La, findLoc) == 0)                    printf("未找到此元素\n");                else                    printf("序号为:%d\n",LocateElem_Sq(La, findLoc));                break;            case 3:                printf("请输入要插入的值及其插入到第几个元素之前: ");                scanf("%d%d",&i,&j);                ListInsert_Sq(&La, j, i);                Print_Sq(La);                break;            case 4:                printf("请输入要删除第几个元素:");                scanf("%d",&i);                if(ListDelete_Sq(&La, i, &k))                    printf("删除的元素的值为 %d\n", k);                else                    printf("输入的序号不合法!");                Print_Sq(La);                break;            case 5:                InitList_Sq(&Lb);                printf("请再输入一组元素: ");                for(i = 0; i < n; i++){                    scanf("%d",&j);                    if(!ListInsert_Sq(&Lb, Lb.length+1, j)){                        printf("空间分配失败!\n");                        exit(OVERFLOW);                    }                }                printf("输入的元素为: ");                Print_Sq(Lb);                printf("将第二组有且第一组没有的元素合并到第一组: ");                Union_Sq(&La, &Lb);                Print_Sq(La);                free(La.elem);                free(Lb.elem);                break;            case 6:                InitList_Sq(&La);                InitList_Sq(&Lb);                InitList_Sq(&Lc);                printf("请再输入两组非降序元素:\n");                printf("第一组: ");                for(i = 0; i < n; i++){                    scanf("%d",&j);                    if(!ListInsert_Sq(&La, La.length+1, j)){                        printf("空间分配失败!\n");                        exit(OVERFLOW);                    }                }                printf("第二组: ");                for(i = 0; i < n; i++){                    scanf("%d",&j);                    if(!ListInsert_Sq(&Lb, Lb.length+1, j)){                        printf("空间分配失败!\n");                        exit(OVERFLOW);                    }                }                MergeList_Sq(La, Lb, &Lc);                printf("按序合并为: ");                Print_Sq(Lc);                break;            case 7:                printf("再见!\n");                end = 1;                break;            default:                printf("无此序号,请重新输入!\n");        }    }    return 0;}Status InitList_Sq(SqList *L){    L->elem = (int*)malloc(LIST_INIT_SIZE * sizeof(ElemType));    if(!L->elem)        return ERROR;    L->length = 0;    L->listsize = LIST_INIT_SIZE;    return OK;}int LocateElem_Sq(SqList L, ElemType e){    /*顺序表L已经存在,返回L中第1个与e相等的数据元素的位序*/    /*若这样的数据元素不存在,则返回值为0*/    ElemType *p;    int i = 1;      //i的初值为第1个元素的位序    p = L.elem;     //p的初值为第1个元素的存储位置    while(i <= L.length && (*p++) != e)     /*并非所有类型的元素都可以使用(*p++) != e判断是否相等*/        ++i;    if(i <= L.length)        return i;    else        return 0;}Status Find_Sq(SqList L, int i, ElemType *e){    if(i < 1 || i > L.length)        return ERROR;    *e = L.elem[i-1];    return OK;}Status ListInsert_Sq(SqList *L, int i, ElemType e){    /*顺序表L已存在,当 1<=i<=ListLength(L)+1 时,在L中第i个位置之前插入新的数据    元素e,L的长度增1*/    ElemType *newbase;    int j;    if(i < 1 || i > L->length+1)    //判断i值是否合法        return ERROR;    if(L->length >= L->listsize){   //当前存储空间已满,增加分配        newbase = (ElemType*)realloc((*L).elem,            ((*L).listsize+LISTINCREMENT)*sizeof(ElemType));        if(!newbase)            return ERROR;        L->elem = newbase;        L->listsize = L->listsize + LISTINCREMENT;    }    for(j = (L->length)-1; j >= i-1; j--)        L->elem[j+1] = L->elem[j];    L->elem[i-1] = e;    ++L->length;    return OK;}Status ListDelete_Sq(SqList *L, int i, ElemType *e){    /*删除顺序表L中的第i个(1<=i<=ListLength(L))数据元素,并用e返回其值,L的长度减1*/    int j;    if(i < 1 || i > L->length)      //判断i值是否合法        return ERROR;    *e = L->elem[i-1];    for(j = i; j < L->length; j++)        L->elem[j-1] = L->elem[j];    L->length--;    return OK;}void Union_Sq(SqList *La, SqList *Lb)   //集合的合并操作{    /*将所有在线性表Lb中但不在La中的数据元素依次插入到La中*/    int e;    int La_len, Lb_len;    int i;    La_len = La->length,    Lb_len = Lb->length;    for(i = 1; i <= Lb_len; i++){        e = Lb->elem[i-1];        if(!LocateElem_Sq(*La,e))            ListInsert_Sq(La, ++La_len, e);    }}void MergeList_Sq(SqList La, SqList Lb, SqList *Lc){    /*已知线性表La和Lb中的数据元素按值非递减排列*/    /*归并La和Lb得到新的线性表Lc,Lc的数据元素也按值非递减排列*/    int i = 0, j = 0, k = 1;    int ai,bj;    InitList_Sq(Lc);    while(i <= La.length-1 && j <= Lb.length-1){        ai = La.elem[i];        bj = Lb.elem[j];        if(ai <= bj){            ListInsert_Sq(Lc,k,ai);            i++;            k++;        }        else{            ListInsert_Sq(Lc,k,bj);            j++;            k++;        }    }    while(i <= La.length-1){        ai = La.elem[i];        ListInsert_Sq(Lc, k, ai);        i++;        k++;    }    while(j <= Lb.length-1){        bj = Lb.elem[j];        ListInsert_Sq(Lc, k, bj);        j++;        k++;    }}void Print_Sq(SqList L){    int i;    for(i = 0; i < L.length; i++)        printf("%d ", L.elem[i]);    printf("\n");}void Print_Hyphen(int n){    int i;    for(i = 0; i < n; i++)        printf("-");}
原创粉丝点击