zoukankan      html  css  js  c++  java
  • 线性表的顺序表示和实现


    /*
    顺序表存储结构容易实现随机存取线性表的第i 个数据元素的操作,但在实现插入、
    删除的操作时要移动大量数据元素,所以,它适用于数据相对稳定的线性表,如职工工资
    表、学生学籍表等。
    c2-1.h 是动态分配的顺序表存储结构,bo2-1.cpp 是基于顺序表的基本操作。由于
    C++函数可重载,故去掉bo2-1.cpp 中算法2.3 等函数名中表示存储类型的后缀_Sq。
    c2-1.h 不采用固定数组作为线性表的存储结构,而采用动态分配的存储结构,这样可以合
    理地利用空间,使长表占用的存储空间多, 短表占用的存储空间少。这些可通过
    bo2-1.cpp 中基本操作函数ListInsert()和图24 清楚看出。
    */

    // c2-1.h 线性表的动态分配顺序存储结构(见图2.1)
    #define LIST_INIT_SIZE 10 // 线性表存储空间的初始分配量
    #define LIST_INCREMENT 2 // 线性表存储空间的分配增量
    struct SqList
    {
    ElemType *elem; // 存储空间基址
    int length; // 当前长度
    int listsize; // 当前分配的存储容量(以sizeof(ElemType)为单位)
    };


    // bo2-1.cpp 顺序表示的线性表(存储结构由c2-1.h定义)的基本操作(12个),包括算法2.3,2.4,2.5,2.6
    void InitList(SqList &L) // 算法2.3
    { // 操作结果:构造一个空的顺序线性表L(见图2.2)
    L.elem=(ElemType*)malloc(LIST_INIT_SIZE*sizeof(ElemType));
    if(!L.elem)
    exit(OVERFLOW); // 存储分配失败
    L.length=0; // 空表长度为0
    L.listsize=LIST_INIT_SIZE; // 初始存储容量
    }
    void DestroyList(SqList &L)
    { // 初始条件:顺序线性表L已存在。操作结果:销毁顺序线性表L(见图2.3)
    free(L.elem);
    L.elem=NULL;
    L.length=0;
    L.listsize=0;
    }
    void ClearList(SqList &L)
    { // 初始条件:顺序线性表L已存在。操作结果:将L重置为空表
    L.length=0;
    }
    Status ListEmpty(SqList L)
    { // 初始条件:顺序线性表L已存在。操作结果:若L为空表,则返回TRUE;否则返回FALSE
    if(L.length==0)
    return TRUE;
    else
    return FALSE;
    }
    int ListLength(SqList L)
    { // 初始条件:顺序线性表L已存在。操作结果:返回L中数据元素的个数
    return L.length;
    }
    Status GetElem(SqList L,int i,ElemType &e)
    { // 初始条件:顺序线性表L已存在,1≤i≤ListLength(L)。操作结果:用e返回L中第i个数据元素的值
    if(i<1||i>L.length)
    return ERROR;
    e=*(L.elem+i-1);
    return OK;
    }
    int LocateElem(SqList L,ElemType e,Status(*compare)(ElemType,ElemType))
    { // 初始条件:顺序线性表L已存在,compare()是数据元素判定函数(满足为1,否则为0)
    // 操作结果:返回L中第1个与e满足关系compare()的数据元素的位序。
    // 若这样的数据元素不存在,则返回值为0。算法2.6
    ElemType *p;
    int 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;
    }
    Status PriorElem(SqList L,ElemType cur_e,ElemType &pre_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)
    { // 初始条件:顺序线性表L已存在
    // 操作结果:若cur_e是L的数据元素,且不是最后一个,则用next_e返回它的后继;
    // 否则操作失败,next_e无定义
    int i=1;
    ElemType *p=L.elem;
    while(i<L.length&&*p!=cur_e)
    {
    i++;
    p++;
    }
    if(i==L.length)
    return INFEASIBLE; // 操作失败
    else
    {
    next_e=*++p;
    return OK;
    }
    }
    Status ListInsert(SqList &L,int i,ElemType e) // 算法2.4
    { // 初始条件:顺序线性表L已存在,1≤i≤ListLength(L)+1
    // 操作结果:在L中第i个位置之前插入新的数据元素e,L的长度加1(见图2.4)
    ElemType *newbase,*q,*p;
    if(i<1||i>L.length+1) // i值不合法
    return ERROR;
    if(L.length>=L.listsize) // 当前存储空间已满,增加分配
    {
    if(!(newbase=(ElemType *)realloc(L.elem,(L.listsize+LIST_INCREMENT)*sizeof(ElemType))))
    exit(OVERFLOW); // 存储分配失败
    L.elem=newbase; // 新基址
    L.listsize+=LIST_INCREMENT; // 增加存储容量
    }
    q=L.elem+i-1; // q为插入位置
    for(p=L.elem+L.length-1;p>=q;--p) // 插入位置及之后的元素右移
    *(p+1)=*p;
    *q=e; // 插入e
    ++L.length; // 表长增1
    return OK;
    }
    Status ListDelete(SqList &L,int i,ElemType &e) // 算法2.5
    { // 初始条件:顺序线性表L已存在,1≤i≤ListLength(L)
    // 操作结果:删除L的第i个数据元素,并用e返回其值,L的长度减1(见图2.5)
    ElemType *p,*q;
    if(i<1||i>L.length) // i值不合法
    return ERROR;
    p=L.elem+i-1; // p为被删除元素的位置
    e=*p; // 被删除元素的值赋给e
    q=L.elem+L.length-1; // 表尾元素的位置
    for(++p;p<=q;++p) // 被删除元素之后的元素左移
    *(p-1)=*p;
    L.length--; // 表长减1
    return OK;
    }
    void ListTraverse(SqList L,void(*vi)(ElemType&))
    { // 初始条件:顺序线性表L已存在
    // 操作结果:依次对L的每个数据元素调用函数vi()
    // vi()的形参加′&′,表明可通过调用vi()改变元素的值
    ElemType *p;
    int i;
    p=L.elem;
    for(i=1;i<=L.length;i++)
    vi(*p++);
    printf("
    ");
    }




    // func2-3.cpp 几个常用的函数
    Status equal(ElemType c1,ElemType c2)
    { // 判断是否相等的函数
    if(c1==c2)
    return TRUE;
    else
    return FALSE;
    }
    int comp(ElemType a,ElemType b)
    { // 根据a<、=或>b,分别返回-1、0或1
    if(a==b)
    return 0;
    else
    return (a-b)/abs(a-b);
    }
    void print(ElemType c)
    {
    printf("%d ",c);
    }
    void print2(ElemType c)
    {
    printf("%c ",c);
    }
    void print1(ElemType &c)
    {
    printf("%d ",c);
    }

    // main2-1.cpp 检验bo2-1.cpp的主程序
    #include"c1.h"
    typedef int ElemType;
    #include"c2-1.h"
    #include"bo2-1.cpp"
    #include"func2-3.cpp" // 包括equal()、comp()、print()、print2()和print1()函数
    Status sq(ElemType c1,ElemType c2)
    { // 数据元素判定函数(平方关系),LocateElem()调用的函数
    if(c1==c2*c2)
    return TRUE;
    else
    return FALSE;
    }
    void dbl(ElemType &c)
    { // ListTraverse()调用的另一函数(元素值加倍)
    c*=2;
    }
    void main()
    {
    SqList L;
    ElemType e,e0;
    Status i;
    int j,k;
    InitList(L);
    printf("初始化L后:L.elem=%u L.length=%d L.listsize=%d
    ",L.elem,L.length,L.listsize);
    for(j=1;j<=5;j++)
    i=ListInsert(L,1,j);
    printf("在L的表头依次插入1~5后:*L.elem=");
    for(j=1;j<=5;j++)
    cout<<*(L.elem+j-1)<<"";
    cout<<endl;
    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);
    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);
    for(j=1;j<=10;j++)
    ListInsert(L,j,j);
    printf("在L的表尾依次插入1~10后:*L.elem=");
    for(j=1;j<=10;j++)
    cout<<*(L.elem+j-1)<<"";
    cout<<endl;
    printf("L.elem=%u L.length=%d L.listsize=%d
    ",L.elem,L.length,L.listsize);
    ListInsert(L,1,0);
    printf("在L的表头插入0后:*L.elem=");
    for(j=1;j<=ListLength(L);j++) // ListLength(L)为元素个数
    cout<<*(L.elem+j-1)<<"";
    cout<<endl;
    printf("L.elem=%u(有可能改变) L.length=%d(改变) L.listsize=%d(改变)
    ",L.elem,L.length,
    L.listsize);
    GetElem(L,5,e);
    printf("第5个元素的值为%d
    ",e);
    for(j=10;j<=11;j++)
    {
    k=LocateElem(L,j,equal);
    if(k) // k不为0,表明有符合条件的元素,且其位序为k
    printf("第%d个元素的值为%d
    ",k,j);
    else
    printf("没有值为%d的元素
    ",j);
    }
    for(j=3;j<=4;j++)
    {
    k=LocateElem(L,j,sq);
    if(k) // k不为0,表明有符合条件的元素,且其位序为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个元素成功,其值为%d
    ",j,e);
    }
    printf("依次输出L的元素:");
    ListTraverse(L,print1); // 依次对元素调用print1(),输出元素的值
    printf("L的元素值加倍后:");
    ListTraverse(L,dbl); // 依次对元素调用dbl(),元素值乘2
    ListTraverse(L,print1);
    DestroyList(L);
    printf("销毁L后:L.elem=%u L.length=%d L.listsize=%d
    ",L.elem,L.length,L.listsize);
    }

    以下是运行的结果代码:

    /*
    初始化L后:L.elem=3615192 L.length=0 L.listsize=10
    在L的表头依次插入1~5后:*L.elem=54321
    L.elem=3615192 L.length=5 L.listsize=10 L是否空:i=0(1:是0:否)
    清空L后:L.elem=3615192 L.length=0 L.listsize=10 L是否空:i=1(1:是0:否)
    在L的表尾依次插入1~10后:*L.elem=12345678910
    L.elem=3615192 L.length=10 L.listsize=10
    在L的表头插入0后:*L.elem=012345678910
    L.elem=3606792(有可能改变) L.length=11(改变) L.listsize=12(改变)
    第5个元素的值为4
    第11个元素的值为10
    没有值为11的元素
    第10个元素的值为3的平方
    没有值为4的平方的元素
    元素0无前驱
    元素1的前驱为0
    元素9的后继为10
    元素10无后继
    删除第12个元素失败
    删除第11个元素成功,其值为10
    依次输出L的元素:0 1 2 3 4 5 6 7 8 9
    L的元素值加倍后:
    0 2 4 6 8 10 12 14 16 18
    销毁L后:L.elem=0 L.length=0 L.listsize=0
    */


  • 相关阅读:
    Unable To Open Database After ASM Upgrade From Release 11.1 To Release 11.2
    11g Understanding Automatic Diagnostic Repository.
    How to perform Rolling UpgradeDowngrade in 11g ASM
    Oracle 11.2.0.2 Patch 说明
    Pattern Matching Metacharacters For asm_diskstring
    Steps To MigrateMove a Database From NonASM to ASM And ViceVersa
    Upgrading ASM instance from Oracle 10.1 to Oracle 10.2. (Single Instance)
    OCSSD.BIN Process is Running in a NonRAC Environment
    Steps To MigrateMove a Database From NonASM to ASM And ViceVersa
    On RAC, expdp Removes the Service Name [ID 1269319.1]
  • 原文地址:https://www.cnblogs.com/KongkOngL/p/3923439.html
Copyright © 2011-2022 走看看