C语言线性表的实现

什么是线性表

        线性表:有同类型数据元素构成有序序列的线性结构

                表中元素个数称为线性表的长度

                线性表没有元素时,称为空表

                表起始位置称为表头,表结束位置称为表尾

线性表的抽象数据类型描述:

        类型名称:线性表

        数据对象集:线性表是n(>=0)个元素构成的有序序列(a1,a2.......)

        操作集:线性表L属于List,整数i表示位置,元素X属于ElementType,线性表基本操作主要有:

        1、List MakeEmpty():初始化一个空线性表L;

        2、ElementType FindKth(int K,List L):根据位序K。返回相应元素;

        3、int Find(ElementType X,List L):在线性表L中查找X的第一次出现的位置;

        4、void Insert(ElementType X,int i,List L):在位序i前插入一个新元素X;

        5、void Delete(int i,List L):删除指定位序i的元素;

        6、int Length(List L):返回线性表L的长度n。

一、线性表的顺序存储实现(数组)

首先创建结构体:

//创建结构体
typedef struct LNide *List;
struct LNode{
    ElementType Data[MAXSIZE];//MAXSIZE是define设定的常数
    int Last;
};
struct LNode L;
List Ptrl;
//访问下标为i的元素:L.Data[i]或PtrL->Data[i]
//线性表的长度为L.Last+1或PtrL->Last

主要操作的实现

        1、初始化(建立空的顺序表)

List MakeEmpty()
{
    List PtrL;
    PtrL = (List)malloc(sizeofz(struct LNode));
    Ptrl->Last = -1;
    return Ptrl;
}

                2、查找

int Find(ElementTyoe,List PtrL)
{
    int i = 0;
    while(i <= PtrL->Last && PtrL->Data[i] != X)
        i++;
    if(i > Ptrl->Last) return -1;
    else return i;
}
//如果没有找到返回-1,如果找到了返回的是存储的位置,即存储元素的下标。
//查找成功的平均次数为(n+1)/2,平均时间性能为0(n)

        3、插入操作实现

void Insert(ElementType X,int i,List PtrL)
{
    int j;
    if(PtrL->Last == MAXSIZE - 1){    //空间已满,不能插入
        printf("表满");
        return;
    }
    if(i < 1 || Ptrl->Last + 2){
        printf("位置不合法");
        return;
    }
    for(j =PtrL->Last;j>=i-1;i++) //将插入元素后面的向后移动,新元素插入,Last仍指向最后元素
        PtrL->Data[j+1] = PtrL->Data[j];
    Ptrl->Data[i-1] = X;
    PtrL->Last++;
    return;
}

4、删除操作实现

void Delete(int i,Last PtrL)
{
    int j;
    if(i < 1 || i > Ptrl->Last + 1){
        printf("不存在第%d个元素");
        return;
    }
    for(j = i;j <= PtrL->Last,j++)
        Ptrl->Data[j-1] = PtrL->Data[j];
    PtrL->Last--;
    return;
}
//将第i个元素后的数据迁移一位,Last仍指向最后元素

二、线性表的顺序存储实现(链表)

1、创建结构体

typedef struct LNode *List;
struct LNode{
    ElementTyoe Data;
    List Next;
};
struct Lnode L;
List PtrL;

2、初始化

List MakeEmpty()
{
    List PtrL;
    PtrL = (List)malloc(sizeofz(struct LNode));
    return Ptrl;
}

3、求表长

int Length(List PtrL)
{
    List p = PtrL;  //p指向表的第一个结点
    int j = 0;
    while(p){
        p = p->Next;
        j++;        //当前p指向的是第j个结点
    }
    return j;
}

4、查找

        按序号查找:FindKth;

List FindKth(int K,List Ptrl)
{
    List p = PtrL;
    int i = 1;
    while(p != NULL && i < k){
        p = p->Next;
        i++;
    }
    if(i == K) return p;  //找到第K个,返回指针
    else return NULL;   //否则返回NULL

                按值查找:Find

List Find(ElementType X,List PtrL)
{
    List p = PtrL;
    while(p != NULL && p->Data != X)
        p = p->Next;
    return p;
}

5、插入

        先构造一个新节点,用s指向;

        再找到链表的第i-1个结点,用p指向;

        然后修改指针,插入节点(p之后插入新节点是s)

        代码如下:

List Insert(ElementType X,int i,List PtrL)
{
    List p,s;
    if(i == 1){            //新节点插入在表头,,申请、填装结点
        s = (List)malloc(sizeof(struct LNode));
        s->Data = X;
        s->Next = PtrL;
        return s;
    }

    p = FindKth(i-1,PtrL);
    if(p == NULL){
        printf("参数i错误");
        return NULL;
    }else{
        s = (List)malloc(sizeof(struct LNode));
        s->Data = X;
        s->Next = p->Next;
        p->Next = s;   
        return PtrL;
}

6 、删除

        先找到链表的第i-1个结点,用p指向;

        再用指针s指向要被删除的结点;

        然后修改指针,删除s所指向结点;

        最后释放s所指向结点的空间。

        代码如下:

List Delete(int i,List PtrL)
{
    List p,s;
    if(i == 1){                                //若要删除的是表的第一个结点
        s = PtrL;                              //s指向第一个结点
        if(Ptrl != NULL) PtrL = PtrL->Next;    //从链表中删除
        else return NULL;
        free(s);
        return PtrL;
    }
    
    p = FindKth(i-1,PtrL);
    if(p == NULL){
        printf("第%d个结点不存在",i-1);
        return NULL;
    }else if(p->Next == NULL){
        printf("第%d个结点不存在",i);
        return NULL;
    }else {
        s = p->Next;                            //s指向第i个结点
        p->Next = s->Next;                      //从链表删除
        free(s);                                //释放被删除结点
        return PtrL;
    }
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值