顺序线性表

来源:互联网 发布:c语言小写变大写 编辑:程序博客网 时间:2024/05/11 01:59

线性表的顺序表示指的是用一组地址连续的存储单元依次存储线性表的数据元素。

线性表的第一个数据元素a1的存储位置,通常称作线性表的起始位置或基地址。

只要确定了存储线性表的起始位置,线性表中任一数据元素都可随机存取,所以线性表的顺序存储结构是一种随机存取的存储结构。

数组类型有随机存取的特性,因此通常都用数组来描述数据接哦故中的顺序存储结构。由于线性表的长度可变,且所需最大存储空间随问题不同而不同,在C语言中可用动态分配的一维数组,如下描述。

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

在上述定义中,数组指针elem指示线性表的基地址,length指示线性表的当前长度。顺序表的初始化操作就是为顺序表分配一个预定定义大小的数组空间,并将线性表的当前长度设为“0”。listsize指示顺序表当前分配的存储空间大小,一旦因插入元素而空间不足时,可进行再分配,即为顺序表增加一个大小为存储LISTINCREMENT个数据元素的空间。

要特别注意的是,C语言中数组的下标是从“0”开始,因此,若L是SqList类型的顺序表,则表中第i个数据元素是L.elem[i-1]。

//构造一个空的线性表Status InitList_Sq(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; //初始存储容量    return OK;}

一般情况下,在第i(1<= i <= n)个元素之前插入一个元素时,需将第n至第i(共n-i+1)个元素向后移动一个位置。如下算法:

//在线性表中插入元素//在顺序线性表L中第i个位置之前插入新的元素e, i的合法值为 1<= i <= ListLength_Sq(L) + 1Status ListInsert_Sq(SqList &L, int i, ElemType e) {    ElemType *newbase = NULL;    ElemType *p = NULL;    ElemType *q = NULL;    if (i <1 || i >L.length + 1) return ERROR;    if (L.length >= L.listsize) {        newbase = (ElemType *)realloc(L.elem, (L.listsize + LISTINCREMENT) * sizeof(ElemType));        if (!newbase) exit(OVERFLOW);        L.elem = newbase;        L.listsize += LISTINCREMENT;    }    q = &(L.elem[i - 1]);  //q为插入位置    for (p = &(L.elem[L.length - 1]); p >= q; --p)         *(p + 1) = *p; //插入位置及之后的元素右移      *q = e;    ++L.length;    return OK;}

删除第i(1<= i <= n)个元素时需将从第i+1至第n(共n-i)个元素依次向前移动一个位置。如下算法:

//删除线性表中的元素//在顺序线性表L中删除第i个元素, 并用e返回其值, i的合法值为 1<= i <= ListLength_Sq(L)Status ListDelete_Sq(SqList &L, int i, ElemType &e) {    ElemType *p = NULL;    ElemType *q = NULL;    if ((i < 1) || (i > L.length)) return ERROR;    p = &(L.elem[i - 1]);   //p为被删除元素的位置    e = *p;    q = L.elem + L.length - 1;    //表尾元素位置    for (++p; p <= q; ++p) *(p - 1) = *p; //被删除元素之后的元素左移    --L.length;   //表长减1    return OK;}

在顺序表L中查访是否存在和e相同的数据元素的最简便的方法是,令e和L中的数据元素逐个比较。如下算法:

int LocateElem_Sq(SqList L , ElemType e , Status (*compare)(ElemType , ElemType)){    //在顺序线性表L中查找第1个值与e满足compare()的元素的位序    //若找到,则返回其在L中的位序,否则返回0    i = 1;     //i的初值为第1个元素的位序    p = L.elem;     //p的初值为第1个元素的存储位置    while(i <= L.length && !(*compare)(*p++ , e))        ++i;    if(i <= L.length)    return i;    else        return 0;}

顺序线性表的实现代码如下:

//线性表的顺序表示与实现 #include <stdio.h>#include <stdlib.h>/******************************************************************************/* 数据类型和常量定义/******************************************************************************/#define TURE         1#define FALSE        0#define OK           1#define ERROR        0#define OVERFLOW    -2typedef int Status;typedef int ElemType;/******************************************************************************/* 数据结构声明/******************************************************************************//* 线性表的动态分配顺序存储结构 */#define LIST_INIT_SIZE 2   /* 线性存储空间的初始分配量 */#define LISTINCREMENT  1   /* 线性存储空间的分配增量 */typedef struct {    ElemType *elem;        /* 存储空间基址 */    int length;            /* 当前长度 */    int listsize;          /* 当前分配的存储容量(以sizeof(ElemType)为单位) */} SqList;//构造一个空的线性表Status InitList_Sq(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; //初始存储容量    return OK;}//在线性表中插入元素//在顺序线性表L中第i个位置之前插入新的元素e, i的合法值为 1<= i <= ListLength_Sq(L) + 1Status ListInsert_Sq(SqList &L, int i, ElemType e) {    ElemType *newbase = NULL;    ElemType *p = NULL;    ElemType *q = NULL;    if (i <1 || i >L.length + 1) return ERROR;    if (L.length >= L.listsize) {        newbase = (ElemType *)realloc(L.elem, (L.listsize + LISTINCREMENT) * sizeof(ElemType));        if (!newbase) exit(OVERFLOW);        L.elem = newbase;        L.listsize += LISTINCREMENT;    }    q = &(L.elem[i - 1]);    for (p = &(L.elem[L.length - 1]); p >= q; --p) *(p + 1) = *p;        *q = e;    ++L.length;    return OK;}//删除线性表中的元素//在顺序线性表L中删除第i个元素, 并用e返回其值, i的合法值为 1<= i <= ListLength_Sq(L)Status ListDelete_Sq(SqList &L, int i, ElemType &e) {    ElemType *p = NULL;    ElemType *q = NULL;    if ((i < 1) || (i > L.length)) return ERROR;    p = &(L.elem[i - 1]);    e = *p;    q = L.elem + L.length - 1;    //表尾元素位置    for (++p; p <= q; ++p) *(p - 1) = *p; //被删除元素之后的元素左移    --L.length;    return OK;}//遍历线性表Status ListTraverse_Sq(SqList &L, Status (*Visit)(ElemType)) {    ElemType *p = NULL;    ElemType *q = NULL;    if (L.length == 0) return ERROR;    p = &(L.elem[0]);    q = L.elem + L.length - 1;    //表尾元素位置    for (; p <= q; ++p) Visit(*p);    return OK;}//访问线性表中的元素Status Visit(ElemType e){    printf("%d ", e);    return OK;}// 测试函数void main(){    SqList L;  InitList_Sq(L); ElemType e;    //遍历空表    if (OK == ListTraverse_Sq(L, Visit)) printf("visit succeed!\n");    //插入元素    if (OK == ListInsert_Sq(L, 1, 10)) printf("insert succeed!\n");    if (OK == ListInsert_Sq(L, 2, 20)) printf("insert succeed!\n");    if (OK == ListInsert_Sq(L, 1, 30)) printf("insert succeed!\n");    if (OK == ListInsert_Sq(L, 2, 40)) printf("insert succeed!\n");    if (OK == ListInsert_Sq(L, 1, 50)) printf("insert succeed!\n");        //遍历非空表    if (OK == ListTraverse_Sq(L, Visit)) printf("visit succeed!\n");    //删除元素    if (OK == ListDelete_Sq(L, 1, e)) printf("delete %d succeed!\n", e);    if (OK == ListDelete_Sq(L, 3, e)) printf("delete %d succeed!\n", e);    if (OK == ListDelete_Sq(L, 2, e)) printf("delete %d succeed!\n", e);    //遍历非空表    if (OK == ListTraverse_Sq(L, Visit)) printf("visit succeed!\n");}




原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 我很懒不想工作怎么办 金寒水冷的八字怎么办 两岁宝宝内八字怎么办 小孩走路脚内八字怎么办 10岁走路内八字怎么办 8岁孩走路内八字怎么办 一岁宝宝足外翻怎么办 2岁宝宝小腿弯怎么办啊 一岁宝宝小腿弯怎么办 一岁小儿o型腿怎么办 两岁宝宝o型腿怎么办 狗狗前腿外八字怎么办 20岁走路内八字怎么办 9岁儿童脚内八字怎么办 5岁宝宝脚内八字怎么办 一岁宝宝内八字怎么办 两人八字合不合怎么办 考到不好的大学怎么办 考的大学不理想怎么办 只考上二本大学怎么办 w7电脑中病毒了怎么办 电脑中病毒了该怎么办 泰迪呼吸急促怎么办啊 狗狗呼吸急促是怎么办 狗狗着凉了呕吐怎么办 狗鼻子流黄鼻涕怎么办 刚出生婴儿睡觉不踏实怎么办 有人溺水后你该怎么办 借钱不还怎么办没欠条 私人欠货款不还怎么办 公司欠货款不还怎么办 两个人离婚一方不同意怎么办 比亚迪l3油耗高怎么办 u盘密码忘记了怎么办 主板没有m.2接口怎么办 点痣留下了疤怎么办 危险三角区长痘痘怎么办 挤了危险三角区怎么办 三角区长痘挤了怎么办 三角区发红长痘怎么办 激光祛斑碰水了怎么办