线性表的顺序存储结构

蹲街弑〆低调 提交于 2020-01-24 18:54:07

顺序存储结构封装需要三个属性:

1.存储空间的起始位置,数组data,它的存储位置就是线性表存储空间的存储位置
2.线性表的最大存储容量,数组的长度MaxSize
3.线性表的当前长度:length

当前长度与数组长度区别:数组长度就是该顺序表的总长度,如果不进行扩容的话,就是不变的。而当前长度在数据的变化中,就会发生相应的变化。

PS:线性表是正常的读数方法,一下标1开始的。

存储时间性能:O(1)

性能:存取以及读取不管是在哪个位置,其时间复杂度都是O(1),而在插入还是删除其时间复杂度都是O(n)

结论:比较适合数据的存取而不适合经常性增删的情况。

顺序存储结构的优缺点

1.优点:
- 无须为表示表中元素之间的逻辑关系而增加额外的存储空间
- 可以快速的存取表中任意位置的元素。
2.缺点:
- 插入以及删除操作需要移动大量的元素。
- 当线性表长度变化较大时,难以确定存储空间的容量。
- 容易造成存储空间的碎片。

具体代码的实现:

// 头文件部分,进行常量参数初始化
#define LIST_INT_SIZE 10  //线性顺序表初始动态分配内存大小
#define INCREAMENT 2    //线性表扩容一次性增量
#define    OK      1
#define   ERROW   -1
#define  OVERFLOW -2


#include<stdio.h>
#include <stdlib.h>//malloc函数包含在其中


typedef int Elemtype;     //线性表的数据类型
typedef int Status;      // 状态数据类型
// 顺序表存储结构定义
typedef struct {
    Elemtype *elem;      //定义线性表内数据元素的数据类型
    int length;          //表当前长度
    int listsize;        //表当前空间容量大小
} SqList;                //表名
// 初始化一个顺序表
Status InitList(SqList &L) {
    L.elem = (Elemtype *)malloc(LIST_INT_SIZE * sizeof(Elemtype)) ;//动态分配内存,分配后可以将l.elem作为数组使用
    if(!L.elem) {                    //对内存分配的结果判断
        exit(OVERFLOW);
    }   //这个地方可以去查一下资料
//  if(L.elem == NULL) {
//      printf("分配内存失败")
//      exit(1);
//  }
    //关于内存分配结果的判断,又该如何去进行判断
    //这种方法进行判断又是否正确
    L.length = 0;                      //对表长初始化归0
    L.listsize = LIST_INT_SIZE;
    return OK;
}

// 创建一个顺序表
Status CreateList(SqList &L) {
    int i;
    InitList(L);
    printf("请输入元素个数:\n");
    scanf("%d",&L.length);
    printf("\n请输入您要输入的元素\n");
    for(i=0; i<L.length; i++) {
        scanf("%d",&L.elem[i]);
    }
    printf("顺序表已创建成功,打印表请选择功能 *3\n");
    return OK;
}
// 顺序表的遍历
Status TraverseList(SqList &L) {
    int i;
    printf("表中元素为:\n");
    for(i=0; i<L.length; i++)
        printf("%d  ",L.elem[i]);
    printf("\n\n顺序表输出完毕!\n");
}
//顺序表的插入
// 表L 位置 i  Elemtype  要插入的元素
Status InsertList(SqList &L,int i,Elemtype e) {
    int* newbase;
    int j;
    if(i < 1 ||i > L.length+1) {   // 判断所要插入的位置
        return ERROW;
    }
    if(L.length>=L.listsize) {
        newbase = (Elemtype*)realloc(L.elem,(L.listsize+INCREAMENT)*sizeof(Elemtype));
        if(!newbase) {
            exit(OVERFLOW);
        }
        L.elem = newbase;
        L.listsize += INCREAMENT;
    }
    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 deleteListElem(SqList &L,int i) {
    Elemtype e;
    int j;
    if(i<1 || i>L.length) {
        return ERROW;
    }
    e = L.elem[i-1];
    for(j = i-1 ; j<=L.length; j++) {
        L.elem[j] = L.elem[j+1];
    }
    L.length--;
    return e;
}
//判断一个值是不是线性表中的元素并返回第几个元素
Status ifElemExit(SqList &L,Elemtype e) {
    int i = 0;
    for(; i<L.length; i++) {
        if(e==L.elem[i])
            break;
    }
    if(i>=L.length) {
        return ERROW;
    } else {
        return i;
    }
}

//输出一个位置的数据元素
Status GetElem(SqList &L,int i) {
    if(i<1||i>L.length) {
        return ERROW;
    }
    return L.elem[i-1];
}
//根据元素的值来进行删除
Status deleteElemByR(SqList &L,Elemtype e) {
    int i = 0;
    i = ifElemExit(L,e);
    if(i==-1) {
        printf("该值不再线性表中:");
        return ERROW;
    } else {
        deleteListElem(L,i+1);
        printf("删除成功!删除的是位置为%d,值为%d",i,e);
        return OK;
    }
}
//将线性表进行递减排序操作
Status SortByMao(SqList &L) {
    Elemtype e;
    for(int j=0; j<L.length; j++) {
        for(int i=0; i<L.length-i-j; i++) {
            if(L.elem[i]<L.elem[i+1]) {
                e = L.elem[i];
                L.elem[i] = L.elem[i+1];
                L.elem[i+1]=e;
            }
        }
    }
}
void UnionTwo(SqList &la,SqList &lb) {
    
    int la_length = la.length;
    int lb_length = lb.length;
    for(int i=1;i<=lb.length;i++){
        Elemtype e= GetElem(Lb,i);
        if(ifElemExit(La,e)==-1){
            InsertList(La,la_length,e);
            la_length++;
            la.length++;
        }
    }
    
    
    
} 


/***主提示输出函数***/


void printlin() {
    printf("\n");
    printf("\t\t\t线性顺序表基本操作学习系统\n");
    printf("\t\t\t      ***主菜单***\n\n");
    printf("\t\t\t    *1 创建一个顺序表\n");
    printf("\t\t\t    *2 定位输出一个数据元素\n");
    printf("\t\t\t    *3 输出顺序表中所有元素\n");
    printf("\t\t\t    *4 定位插入一个数据元素\n");
    printf("\t\t\t    *5 定位删除一个数据元素\n");
    printf("\t\t\t    *6 定值删除一个数据元素\n");
    printf("\t\t\t    *7 清空顺序表\n");
    printf("\t\t\t    *8 销毁顺序表\n");
    printf("\t\t\t    *9 对表内数据元素进行非递减排序\n");
    printf("\t\t\t    *0 结束程序\n");
}
//清空线性表
void clearList(SqList &L) {
    if(L.length!=0) {
        L.length = 0;   //由于顺序表的用得是与数组一样的内存空间,
        //所以标的清空只要将表长归零即可,由此可见,表长是线性表非常重要的部分
    }
}
//销毁线性表
void destoryList(SqList &L) {
    if(L.length!=0) {
        free(L.elem);
        L.elem = NULL;//使用free后就需要对元素进行赋空操作
    }

}



int main() {
    int i,j,k;
    Elemtype e;
    SqList L;
    L.length=0;
    printf("编写此程序目的是自我学习线性表顺序表\n");
    printlin();
    while(1) {
        int t;
        scanf("%d",&t);
        if(t!=0)
            if(t==1||L.length!=0) {
                switch(t) {
                    case 1:
                        if(L.length!=0) {
                            printf("顺序表已存在,是否重新创建顺序表?\n");
                            printf("*1 是   *2 否\n");
                            scanf("%d",&i);
                            if(i==1)
                                CreateList(L);
                        } else
                            CreateList(L);
                        break;
                    case 0:
                        break;
                    case 3:
                        TraverseList(L);
                        break;
                    case 7:
                        clearList(L);
                        printf("清空完毕,返回主菜单\n\n");
                        break;
                    case 4:
                        printf("输入要插入的位置\n");
                        scanf("%d",&i);
                        printf("请输入要插入的数据\n");
                        scanf("%d",&j);
                        k=InsertList(L,i,j);
                        if(k==-1) {
                            printf("插入位置不合法,插入数据操作失败!\n\n");
                        } else
                            printf("插入数据成功\n\n");
                        break;
                    case 5:
                        printf("请输入要删除数据位置\n");
                        scanf("%d",&i);
                        e = deleteListElem(L,i);
                        printf("删除掉的元素是第%d个位置,它的值是%d",i,e);
                        break;
                    case 2:
                        printf("请输入要需要得到数据位置:");
                        scanf("%d",&i);
                        e = GetElem(L,i);
                        printf("第%d个位置上的元素值为:%d",i,e);
                        break;
                    case 6:
                        printf("请输入需要删除的值:");
                        scanf("%d",&e);
                        deleteElemByR(L,e);
                        break;
                    case 8:
                        destoryList(L);
                        printf("销毁成功!");
                        break;
                    case 9:
                        SortByMao(L);
                        break;
                    default: {
                        printf("输入有误,可以重新选择,退出按0!\n");
                    }
                }
            } else
                printf("顺序表未创建或已清空或销毁,请先创建顺序表\n");
        system("pause");
        system("CLS");
        printlin();
        if(t==0)
            break;
    }
    return 0;
}

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!