数据结构与算法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; 
   }
  

}

 

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

 

posted on 2017-06-22 21:06  guoshiyv  阅读(175)  评论(0编辑  收藏  举报

导航