数据结构学习笔记-链表

什么是线性表

线性表(Linear List)由同类型数据元素构成有序序列的线性结构

  • 表中元素个数称为线性表的长度
  • 线性表没有元素时,称为空表
  • 表起始位置称为表头,结束位置称为表尾

数据对象集:n个元素构成的有序序列

操作集

L表示一个线性表,整数i表示位置,元素X属于ElementType

ElementType表示一种数据类型,可以是整形也可以是实型,也可以是结构


List MakeEmpty():初始化一个空线性表

ElementType Findkth(int k,LIst L):返回位序K的元素

int Find(ElementType X,List L):查找X在L内第一次出现的位置

void insert(ElementType X,int i,List L):给L在位序i前插入一个元素X

void Delete(int i,List L):删除L内位序为i的元素

int Lenth(List L):返回L的长度

线性表的顺序存储实现
typedef struct LNode *List//List存放该结构的地址
struct LNode{//定义一个名为LNode的结构
    ElementType Data[MAXSIZE];
    int Last;//线性表最后一位的位序
};
struct LNode L; //声明一个结构体
List PtrL; //声明该结构体的指针

访问下标为i的元素:L.Data[i]或PtrL->Data[i]

线性表的长度:L.Last+1或PtrL->Last+1 因为Last从0开始,所以长度为Last+1

"->“表示取出PtrL指向的结构体中的某个数据,与”.“类似,当声明一个指针变量时想要取出该结构体中的数据就需要”->",而声明一个普通的变量是使用"."即可

主要操作实现
  1. 初始化(建立空顺序表)

    List MakeEmpty(){
        List Ptrl; //声明该结构体的指针
        PtrL = (List)malloc(sizeof (struct LNode));
        Ptrl->Last = -1;//当表内没有数据时Last为-1
        return Ptrl;
    }
    
  2. 查找 O(n)

int Find(ElementType X,List PtrL){
    int i = 9;
    while(i <= PtrL->Last && PtrL->Data[i]!= x){//循环结束有两个原因一个是i>last说明,找完了还没有,另一个是Data[i] = X说明找到了
        i++;
    }
    if(i > PtrL->Last)
        return -1;
    else 
        return i;
}
  1. 插入(第i(1<=i<=n+1)个位置上插入一个值位X的新元素)

在第i个位置插入实际上就是插在下标位i-1的位置,首先把原来的数据从i-1开始依次向后移(从后往前),然后把数据插到i-1,

void Insert(ElementType X,int i,List PtrL){
    int j;
    if(PtrL->Last == MAXSIZE-1){ //判断表的最后一位是否已经到达MAXSIZE,-1是因为表的下标从0开始
        printf("表满");
        return;
    }
    if(i < 1 || i > PtrL->Last+2){ //或者可以写成(i-1 < 0 || i-1 > PtrL->Last+1)+1确保还有剩余位置
        printf("位置不合法");
        return;
    }
    for(j = PtrL->Last;j >= i-1;j++){ //从最后一位开始,循环到i-1这个位置(O(n))
        Ptrl->Data[j+1] = Ptrl->Data[j];//每个数据往后移动一位
    }
    PtrL->Data[i-1] = X;//令原本下标为i-1的位置为X
    PtrL->Last++;//表长+1
}
  1. 删除(第i个位置)
void Delete(int i,List PtrL){
    int j;
    if(i < 1 || PtrL->Last+1){ //此处为删除因此不需要保存余量,只需小于Last+1即可
        printf("不存在");
        return;
    }
    for(j = i;j <= PtrL->Last;j++){//从i+1开始到结束的值都向前移动一位
        PtrL->Data[j-1] = PtrL->Data[j];
    }
    PtrL->Last--;
    return;
}
线性表链式存储实现

在链表内插入只需要修改链,但是查找第i个元素和查看链表长度就比较复杂

typedef struct LNode *List;
struct LNode{
    ElementType Data;//存储数据
    List Next;//下一个链表的头。
};
Struct LNode L;
List PrtL;
  1. 求表长
int Length(List PtrL){
    List p = PtrL; //p指向表的第一个节点
    int j = 0;
    while(p){//若返回NULL即到最后一位,则循停止
        p = p->Next; //指向下一个节点
        j++;//计数
    }
    return j;
}
  1. 查找

    1. 按序号查找

      List FindKth(int K,List PtrL){
          List p = PtrL;
          int i = 1; //表头为一
          while(p != NULL && i < K){//第一个条件是表不能到结尾,第二个是刚好遍历到K就停止
              p = p->Next;//转到下一节点
              i++;//计数
          }
          if(i == K) //等于说明找到了
              return p;//返回该节点的指针
          else
              return NULL;
      }
      
    2. 按值查找

      List Find(ElementType X,List PtrL){
          List p = Prtl;
          while(X != P->Data && p != NULL){
              p = p->Next
          }
          if(p->Data == X)
      		return p;
          else
              return NULL;
      }
      
  2. 插入(在i-1(1<=i<=n+1)个节点后插入一个值为X的新节点)之所以插入到i-1之后是因为,想给链表插入节点,需要知道前面一个节点的信息

List insert(ElementType X,int i,List PtrL){//List PtrL 传入的是表头的指针
    List p,s;
    if(i == 1){//1在表头位置需要特殊处理
        s = (List)malloc(sizeof(struct LNode));//申请一块空间
        s->Data = X;
        s->Next = PtrL;//将这下个节点的Next赋给此节点的Next
        return s;//返回表头
    }
    p = FindKth(i-1,PtrL);
    if(p == NULL){
        printf("error");
        return NULL;
    }
    else{
        s = (List)malloc(sizeof(struct LNode));
        s->Data = X;
        s->Next = p->Next;//把i-1的链接给要插入的节点
        p->Next = s;//把要插入的节点的链接给i-1
        return PtrL;
    }
}
  1. 删除
List Delete(int i,List PtrL){
	List p,s;
    if(i == 1){//1特殊化
        s = PtrL;
        if(PtrL!=NULL) //查看这个表是否无节点
            PtrL = PtrL->Next; //是表头变为下一个节点
        else
            return NULL;
        free(s); //释放被删除的节点
        return PtrL;
    }
    p = FindKth(i-1,List PtrL); //查找第i-1个节点
    if(p == NULL){ //判断输入的i是否在范围内
        printf("第%d个节点不存在",i-1);
    }
    else if(p->Next == NULL){  //判断输入的节点是否是表的结尾
        printf("第%d个节点不存在",i);
    }
    else{
        s = p->Next;
        p->Next = s->Next;
        free(s);
        return PtrL;
    }
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值