数据结构2 - 速写一个链表 About Linked List

1)较于顺序表,其存储地址不连续,但能灵活控制存储长度,以及增删改查的操作

2)定义四板

(1)typedef板

typedef struct LNode *List;

(2)struct板

struct LNode{
    //比起ElemType,还是int比较直观,当然清楚int可以换其他类型即可
    int Data;
    //指向下一个数据的指针
    List Next;
};

(3)LNode 建

LNode L;

(4)List 建

List PtrL;

接下来是对链表的操作

1.求表长

int Length(List PtrL)
{
    int n=0;
    List P = PtrL;
    //判断条件即P往下延顺时是否到空了
    //别用PtrL判断,这样原始数据都被丢到姥姥家去了
    while(P)
    {
        P=P->Next;
        n++;
    }
   return n;     
}

2.查找

1)按序号查找

//按序号PositionK查找,返回该结点
List FindByKey(int PositionK, List PtrL)
{
    //新建一个指针P去操作
    List P = PtrL;
    //用i与位置PositionK去比较
    int i=1;
    //while遍历 两个条件:i比PositionK小,链表剩余部分不空
    while(i < PositionK && P != NULL)
    {
        P = P->Next;
        i++;//相当于i不断向PositionK靠近
    }
    //此判断是为了防止while循环 是因为 P空了--即i大于了表长 而采取的
    if(i==K) return P;
    else return NULL;
}

 2)按值查找

//按value查找 返回该结点
List FindByValue(int value,List PtrL)
{    
    //同样建指针
    List P = PtrL;
    //while判断 条件略微改变
    while(P -> Data != value && P != NULL)
    {
        P = P -> Next;        
    }
    //再判断 确保不空
    if(P->Data == value) return P;
    else return NULL;
}

 3)插入(即增添)

List Insert(int value,int position,List PtrL)
{
    //p用于延顺查找要插入的位置, s用于建立新空间存储新数据
    List p,s;
    //要插入的位置是表头
    if(i == 1)
    {
        //建空间
        s=(List)malloc(sizeof(struct LNode));
        //存数据
        s->Data=value;
        //直接指向传进的参数PtrL即可
        s->Next=PtrL;
        //返回s即可,此时这个链表以s打头,后面接着原来PtrL的数据
        return s;
    }
    //用传进来的位置序号来找
    p=FindByKey(position-1,PtrL);
    //先判断是否为空--没找到合法位置
    if(p==NULL)
    {
        return NULL;
    }
    else
    {
        s=(List)malloc(sizeof(struct LNode));
        s->Data=value;
        //只提供快速写法,无原理
        //因为此时p->Next有着该位置之下的所有数据,用s指过去
        s->Next=p->Next;
        //结点p指向s即可
        p->Next=s;
    }
    return PtrL;
}

4)删除

List Delete(int position,List PtrL)
{
    //原理如上
    List p,s;
    //删的是表头的数据
    if(i==1)
    {
        s=PtrL;
        //不为空就直接将表头=表头->Next,就是删除了
        if(Ptrl != NULL)
            PtrL = PtrL->Next;
        //都为空了还删个derder
        else 
            return NULL;  
        //s存是防止意外,此段中可以用s取代PtrL的所有操作,然后return s 
        //这里没用上s就释放掉吧
        free(s);//要快速写实际上不用s还更好 OUO
        return PtrL; 
    }
    p=FindByKey(position-1,PtrL);
    //先判断p是否为空
    if(p==NULL) return NULL;
    //开始操作
    else
    {
        s=p->Next;
        p->Next=s->Next;
        //这里我编辑时犯下过一个误区,当s指向找到的p->Next时,通过这两步操作将结点删除后
        //我犹豫起了是返回s还是p,最后绕深了,才发现PtrL是能被改变的
        //而不是将PtrL赋给p或s之后来执行删除,PtrL无法改
        //return PtrL;
        //而且根据VS2022的牛马设计,在最外层一定要返回一个数才行,任何嵌套里的返回它看不见
    }
    return PtrL;
}

此次编辑离上次竟相隔22天,中间忙着学习MySQL,Linux;编辑时也出现几次难点,因为接触的链表版本比较多,而且时间沉淀后发现其中的不对劲,优化时又拖了一段时间思考,思考到一半溜去学别的了,现在敲完实在阿巴阿巴

可能中间有些错误,请有心的读者以怀疑一切的态度观看,也请方便指出错误

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值