线性表的顺序表示与实现

#include <stdio.h>
#include <stdlib.h>
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define INFEASIBLE -1 //不能实行 
#define OVERFLOW -2
#define LIST_INIT_SIZE 100  //顺序表初始分配空间
#define LISTINCREMENT 10    //顺序表存储空间分配增量
typedef int Status;                        
//Status是函数的类型,其值是函数结果状态码
typedef int ElemType;
//顺序表存储元素类型, 考虑到可移植性, 若改变存储类型, 只需修改这一处,比较方便
//自定义结构体 
typedef struct{
    ElemType *elem;     //存储空间地址
    int length;         //当前长度
    int listsize;       //当前分配的存储容量(以sizeof(ElemType)为单位)
    }SqList;
//函数声明方便调用 
void Init_Sq(SqList *L);//初始化列表 
Status Insert_Sq(SqList *L, int i, ElemType e);//插入 
Status Destroy_Sq(SqList *L);//销毁 
Status Delete_List(SqList *L, int i);//删除 
void Travse_Sq(SqList *L);//逆序 
ElemType Next_Elem(SqList *L, int cur_elem);//后继 
ElemType Prior_Elem(SqList *L, int cur_elem);//前驱 
ElemType GetElem(SqList *L, int i);//获取元素 
int LocateElem_Sq(SqList *L, ElemType e);//定位元素 
Status compare(ElemType e1, ElemType e2);//比较元素 
int ListLength(SqList *L);//获取表长 
void union_Sq(SqList *La, SqList *Lb);//连接多表 
void Merge_Sq(SqList *La, SqList *Lb, SqList *Lc);//合并多表 
int main()
{
SqList La;//声明列表La 
SqList Lb;//声明列表Lb 
SqList Lc;//声明列表Lc 

Init_Sq(&La); //初始化列表La

Init_Sq(&Lb); //初始化列表Lb

if(Insert_Sq(&La, 1, 4))
    {
     printf("The element in La is %d\n", GetElem(&La, 1));
    }
if(Insert_Sq(&La, 2, 5))
    {
     printf("The element in La is %d\n", GetElem(&La, 2));
    }
if(Insert_Sq(&La, 3, 6))
    {
     printf("The element in La is %d\n", GetElem(&La, 3));
    }
if(Insert_Sq(&La, 4, 8))
    {
     printf("The element in La is %d\n", GetElem(&La, 4));
    }
if(Insert_Sq(&La, 5, 18))
    {
     printf("The element in La is %d\n", GetElem(&La, 5));
    }

printf("\n");
if(Insert_Sq(&Lb, 1, 4))
    {
     printf("The element in Lb is %d\n", GetElem(&Lb, 1));
    }
if(Insert_Sq(&Lb, 2, 15))
    {
     printf("The element in Lb is %d\n", GetElem(&Lb, 2));
    }
printf("\n");

Merge_Sq(&La, &Lb, &Lc);//合并多表 
printf("After merge La and Lb:\n");
Travse_Sq(&Lc);//逆序表Lc 
Destroy_Sq(&La);//销毁表La 
Destroy_Sq(&Lb);//销毁表Lb
Destroy_Sq(&Lc);//销毁表Lc
}
void Init_Sq(SqList *L)//初始化列表函数 
{
    L->elem = (ElemType *)malloc(LIST_INIT_SIZE * sizeof(ElemType));//分配初始空间 
    if(L->elem == NULL)//如果初始化后为空 
        {
            printf("Memory allocation is error!");
            exit(1);//0表示正常退出,非零表示异常退出
        }
    L->length = 0;//长度为零 
    L->listsize = LIST_INIT_SIZE;//列表长度为初始长度 
}
//在第i个位置插入元素e
Status Insert_Sq(SqList *L, int i, ElemType e)
{
    ElemType *newbase;  //指向新增顺序表后的起始位置
    ElemType *p;
    ElemType *q;
    if(i < 1 || i > L->length + 1)
        {
            printf("The location that inserted is illegal!\n");
            return TRUE;
        }
    if(!(L->length < L->listsize))  //如果顺序表满了就扩充
        {
            newbase = (ElemType *)realloc(&L->elem,(L->length + LISTINCREMENT) * sizeof(ElemType));
        } 
    p = &L->elem[i-1];
    for(q = &L->elem[L->length - 1]; p <= q; q--)
    {
        *(q + 1) = *q;
    }
    *p = e;
    L->length ++;
    return TRUE;
}
//销毁顺序表
Status Destroy_Sq(SqList *L)
{
    if(L->length < 1)
        return FALSE;
    free(L->elem);    
    L->elem = NULL;
    return TRUE;
}
//删除顺序表中指定元素
Status Delete_List(SqList *L, int i)
{
    ElemType *p;
    int j;
    if(i < 1 && i > L->length)
        {
            printf("The site that store element is not exist!\n");
            return FALSE;
        }
    p = &L->elem[i - 1];  //初始使p指向将要删除的位置
    for(j = i - 1; j < L->length - 1; j++)
        {
            *p = *(p+1);
            p++;
        }
    L->length --;
    return TRUE;
}
//遍历顺序表
void Travse_Sq(SqList *L)
{
    int i;
    if(L->length == 0)
        {
            printf("The sequence list is empty!\n");
        }
    else
    for(i = 0; i < L->length; i++)
        printf("The No.%d is %d.\n", i, L->elem[i]);
}
//返回第i个数据
ElemType GetElem(SqList *L, int i)
{
    if(i < 1 || i > L->length)
        return ERROR;
    return L->elem[i - 1];
}
//返回第cur_elem个元素的直接前驱
ElemType Prior_Elem(SqList *L, int cur_elem)
{
    if(cur_elem == 1)
        return ERROR;
    else
        return L->elem[cur_elem - 2];
}
//返回第cur_elem个元素的直接后继
ElemType Next_Elem(SqList *L, int cur_elem)
{
    if(cur_elem == (L->length - 1))
        return FALSE;
    else
        return L->elem[cur_elem];
}
//记录线性表的长度
int ListLength(SqList *L)
{
    if(L->length == 0)
        {
            printf("The sequence list is empty!\n");
            return 0;
        }
    else
        return L->length;

}
//线性表A和B作并集操作
void union_Sq(SqList *La, SqList *Lb)
{
    //将所有在线性表Lb中但不在La中的数据元素插入到La中
    int La_len, Lb_len;
    int i;
    int Lb_cur_elem; //记录Lb中取出的元素
    La_len = ListLength(La);//表a长度 
    Lb_len = ListLength(Lb);//表b长度
    //注意,取的是第i个元素,从1开始计数
    //GetElem()函数中会做减1处理(计算机的计数方式)
    for(i = 1; i <= Lb_len; i++)
        {
            Lb_cur_elem = GetElem(Lb, i);
            if(!LocateElem_Sq(La, Lb_cur_elem))
            Insert_Sq(La, ++La_len, Lb_cur_elem);
        }
}
Status compare(ElemType e1, ElemType e2)
{
    if(e1 == e2)
        return TRUE;
    else
        return FALSE;
}
//在顺序线性表L中查找第一个值与e满足compare()的元素的位序
//若找到,则返回其在L中的位序,否则返回0
int LocateElem_Sq(SqList *L, ElemType e)
{
    int i;
    ElemType *p;
    i = 1; //i的初值为第一个元素的位序
    p = L->elem; //p的初值为第1个元素的存储位置
    while(i <= L->length && (e != *p++))
        i++;
    if(i <= L->length)
        return i;
    else
        return 0;
}
//已知顺序线性表La,和Lb的元素按值非减排列
//归并La和Lb得到新的顺序线性表Lc,Lc的元素也是按值非减排列
void Merge_Sq(SqList *La, SqList *Lb, SqList *Lc)
{
    ElemType *pa;
    ElemType *pb;
    ElemType *pc;
    ElemType *pa_last;
    ElemType *pb_last;
    //给Lc的elem元素分配空间
    Lc->elem = (ElemType *)malloc((La->length + Lb->length) * sizeof(ElemType));
    if(!Lc->elem)
        {
            printf("Error!\n");
            exit(1);
        }
    pa = La->elem;  //pa指向La的第一个元素
    pb = Lb->elem; //pb指向Lb的第一个元素?? ??? ?
    pc = Lc->elem;  //pc指向Lc的首地址
    Lc->length = La->length + Lb->length;
    pa_last = &La->elem[La->length - 1];  //指向La的最后一个元素(La中的最大的元素)
    pb_last = &Lb->elem[Lb->length - 1];  //指向Lb的最后一个元素(Lb中的最大的元素)
    while(pa <= pa_last && pb <= pb_last)  //实现归并
        {
            if(*pa <= *pb)
                {
                *pc++ = *pa++;
                }
            else
                *pc++ = *pb++;
        }
    while(pa <= pa_last)
        *pc++ = *pa++;
    while(pb <= pb_last)
        *pc++ = *pb++;
}

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值