顺序表

顺序表

简而言之,用数组表示线性关系


基本结构

//函数结果状态代码
#define TRUE 1
#define FALUSE 0
#define OK 1
#define ERROR 0
#define INFEASIBLE -1
#define OVERFLOW -2

typedef int DataType;   /*数据类型*/
typedef int ElemType;   /*元素类型*/

//--------------线性表的动态顺序存储结构------------
#define LIST_INIT_SIZE 100  //线性表存储空间的初始分配量
#define LISTINCREMENT 10    //线性表存储空间的分配增量
typedef struct
{
    ElemType *elem; //存储空间地址,动态改变所指内存的大小
    int length;     //当前长度
    int listsize;   //当前分配的存储容量
}SqList;

函数

  • 初始化
void 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;    //初始容量
}

void* realloc(void* ptr, unsigned newsize);
参数说明:
给一个已经分配了地址的指针重新分配空间,参数ptr为原有的空间地址,newsize是重新申请的地址长度.
理解:
realloc可以对给定的指针所指的空间进行扩大或者缩小,无论是扩张或是缩小,原有内存的中内容将保持不变.当然,对于缩小,则被缩小的那一部分的内容会丢失.realloc并不保证调整后的内存空间和原来的内存空间保持同一内存地址.相反,realloc返回的指针很可能指向一个新的地址

  • 插入元素
void ListInsert(SqList *L, int i, ElemType e)
//在第i位置处插入e
//最小插入表头,位置为第i个
//最大插入表位,位置为第L.length+1
{
    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]);       //插入位置地址
    ElemType *p = &(L->elem[L->length-1]);//最后一个位置的地址
    while(p >= q)                       //插入位置及之后的元素向后移动
    {
        *(p+1) = *p;
        p--;
    }
    *q = e;

    ++L->length;
}
  • 删除元素
void ListDelete(SqList *L, int i, ElemType *e)
//删除第i个元素,并用e返回值
//最小插入表头,位置为第i个
//最大插入表位,位置为第L.length
{
    ElemType *p = &(L->elem[i-1]);
    ElemType *q = L->elem+L->length-1;    //表尾位置
    *e = *p;

    for(++p; p <= q; ++p)               //插入位置之后像左移动
    {
        *(p-1) = *p;
    }

    --L->length;
}
  • 寻找元素
int cmp(ElemType a, ElemType b)
//判断两个元素是否相等
{
    return a == b;
}
int LocateElem(SqList *L, ElemType e, int(*cmp)(ElemType, ElemType))
//查找第1个值与e相同cmp()的元素的位序
//若找到,则返回e在L中的位序,否则返回0
{
    int i = 1;                          //初值为第一个元素的位序
    ElemType *p = L->elem;                        //初值为第一个元素的地址

    while(i <= L->length && !cmp(*p++, e))
        ++i;

   if(i <= L->length)
        return i;
   else
        return 0;
}
  • 归并有序表
void ListMerge(SqList *La, SqList *Lb, SqList *Lc)
//La, Lb的元素按值非递减排列
//归并La,Lb得到Lc,按非递减排列
{
    ElemType *pa = La->elem;
    ElemType *pb = Lb->elem;
    Lc->listsize = Lc->length = La->length+Lb->length;

    ElemType *pc = Lc->elem = (ElemType*)malloc(Lc->listsize*sizeof(ElemType));
    if(!Lc->elem)
        exit(OVERFLOW);
    ElemType *pa_last = La->elem+La->length-1;
    ElemType *pb_last = Lb->elem+Lb->length-1;

    while(pa <= pa_last && pb <= pb_last)       //归并
    {
        if(*pa <= *pb)
            *pc++ = *pa++;
        else
            *pc++ = *pb++;
    }
    while(pa <= pa_last)                        //插入La的剩余部分
        *pc++ = *pa++;
    while(pb <= pb_last)                        //插入Lb的剩余部分
        *pc++ = *pb++;
}


测试代码

#include <stdio.h>
#include <stdlib.h>

//函数结果状态代码
#define TRUE 1
#define FALUSE 0
#define OK 1
#define ERROR 0
#define INFEASIBLE -1
#define OVERFLOW -2

typedef int DataType;   /*数据类型*/
typedef int ElemType;   /*元素类型*/

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

void 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;    //初始容量
}

void ListInsert(SqList *L, int i, ElemType e)
//在第i位置处插入e
//最小插入表头,位置为第i个
//最大插入表位,位置为第L.length+1
{
    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]);       //插入位置地址
    ElemType *p = &(L->elem[L->length-1]);//最后一个位置的地址
    while(p >= q)                       //插入位置及之后的元素向后移动
    {
        *(p+1) = *p;
        p--;
    }
    *q = e;

    ++L->length;
}


void ListDelete(SqList *L, int i, ElemType *e)
//删除第i个元素,并用e返回值
//最小插入表头,位置为第i个
//最大插入表位,位置为第L.length
{
    ElemType *p = &(L->elem[i-1]);
    ElemType *q = L->elem+L->length-1;    //表尾位置
    *e = *p;

    for(++p; p <= q; ++p)               //插入位置之后像左移动
    {
        *(p-1) = *p;
    }

    --L->length;
}

int cmp(ElemType a, ElemType b)
//判断两个元素是否相等
{
    return a == b;
}
int LocateElem(SqList *L, ElemType e, int(*cmp)(ElemType, ElemType))
//查找第1个值与e相同cmp()的元素的位序
//若找到,则返回e在L中的位序,否则返回0
{
    int i = 1;                          //初值为第一个元素的位序
    ElemType *p = L->elem;                        //初值为第一个元素的地址

    while(i <= L->length && !cmp(*p++, e))
        ++i;

   if(i <= L->length)
        return i;
   else
        return 0;
}

void ListMerge(SqList *La, SqList *Lb, SqList *Lc)
//La, Lb的元素按值非递减排列
//归并La,Lb得到Lc,按非递减排列
{
    ElemType *pa = La->elem;
    ElemType *pb = Lb->elem;
    Lc->listsize = Lc->length = La->length+Lb->length;

    ElemType *pc = Lc->elem = (ElemType*)malloc(Lc->listsize*sizeof(ElemType));
    if(!Lc->elem)
        exit(OVERFLOW);
    ElemType *pa_last = La->elem+La->length-1;
    ElemType *pb_last = Lb->elem+Lb->length-1;

    while(pa <= pa_last && pb <= pb_last)       //归并
    {
        if(*pa <= *pb)
            *pc++ = *pa++;
        else
            *pc++ = *pb++;
    }
    while(pa <= pa_last)                        //插入La的剩余部分
        *pc++ = *pa++;
    while(pb <= pb_last)                        //插入Lb的剩余部分
        *pc++ = *pb++;
}

void ListTraverse(SqList *L)
{
    int n = L->length, i;

    for(i = 0; i < n; i++)
        printf("%d ", L->elem[i]);
    printf("\n");
}
int main()
{
    SqList La, Lb, Lc;
    InitList(&La);
    InitList(&Lb);

    ListInsert(&La, 1, 1);
    ListInsert(&La, 2, 2);
    //ListInsert(&La, 3, 3);
    ListInsert(&La, 3, 4);
    ListTraverse(&La);

    ListInsert(&Lb, 1, 1);
    ListInsert(&Lb, 2, 2);
    ListInsert(&Lb, 3, 3);
    ListInsert(&Lb, 4, 4);
    ListTraverse(&Lb);

    int e;
    ListInsert(&La, 3, 3);
    ListDelete(&La, 2, &e);
    ListTraverse(&La);

    ListMerge(&La, &Lb, &Lc);
    ListTraverse(&Lc);
    printf("%d",LocateElem(&Lc, 2,cmp));
    return 0;
}
  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值