• 数据结构与算法2—— 线性链式存储


      线性链式存储:

         包含两部分:1.存储的单个元素

                                        2.指针,指向下一个的地址

    typedef struct()
    {
         ElementType Data;
         struct Node *Next;
    }List ;
    List L,Ptrl;

           Ps:算法应保证具有可移植性,(ElementType)

      表长函数,相比顺序数组存储复杂,需要遍历所有元素

           定义一个新指针,始终指向当前的这个链表。

    int length(List *Ptrl)
    {   int i=0;
        List *p=Ptrl;
        while(p!=NULL)
           { p=p->Next; //通过指针实现了链表的链接
            i++:}
          return i;
    
    }

       下面进行查找数据,有两种查询方式,一种按第几个元素查找,一种按数据值查找。

    按第几个元素查找:
    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;
        else return NULL;
    
    }                              

            K有查找范围,处理特殊情况时候:1. K<1 ,直接执行return NULL

                                                                   2.K>链表长度的时候 此时p=Null,也是return NULL

                                                                   3.因此不可以直接 return p; 

    按数据值查询:
    List *FindKth(List *Ptrl,ElementType x)
    {
         List *p=Ptrl;
         while(p!=NULL && p->Data!=x)
                  p=p->Next;
         return p;
    }

               由于没有类似的K值的限制,可以直接return p

     

               插入数据,在第i个位置插入数据时,相当于改变i-1以后,注意代码顺序

               成功返回新的链表的首地址,有问题失败时返回NULL;

     

    List *add(ElementType x,List *Ptrl,int i)
    {  List *p,*s;
        if(i==1)
        {
           s=(List *)malloc(sizeof(List));
           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(List));
           s->Data=x;           //构造数据
           s->Next=p->Next;
           p->Next=s;
           return Ptrl;
        }
    }

                删除数据,最大的难点在于一定要释放被删除的数据,否则会造成内存泄漏

    List *Delete(List *Ptrl,int i)
    {
       List *p,*s;
       if(i==1)
       {
         s=Ptrl;
         Ptrl=Ptrl->Next;
         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;
              p->next=s->next;
              free(s);  释放地址
              return Ptrl; 
       }
      
    
    }

        两者都要单独考虑插入/删除第一个元素的情况,因为改变了首地址。

  • 相关阅读:
    MTLLoader 报 Handlers.get() has been removed. Use LoadingManager.getHandler() instead 错误处理
    uniCloud云开发已实现五端上线【言语录书】
    v-model 双向绑定 vue3.x
    javascript 集合操作
    链表操作
    vue3 父子组件双向数据绑定
    二叉树排序
    自制Chrome扩展插件:用于重定向js
    解析Markdown文件生成React组件文档
    微前端框架single-spa初探
  • 原文地址:https://www.cnblogs.com/guoshiyv/p/7067211.html
Copyright © 2020-2023  润新知