链表算法三之静态链表

   本节知识来源于大话数据结构,代码基本上也是参考这本书,引用书上原文,对于早期的编程语言,没有指针的概念,怎么实现链表,静态链表的想法就是用数组来模拟指针,其实我感觉静态链表的思想很重要,而使用静态链表基本很少,比如并查集的思想我感觉就是静态链表的应用。

   需要注意的是数组第一个和最后一个元素不存数据,其中下标为0的元素的cur存放备用链表的第一个结点的下标,其实就是第一个空闲元素的下标,而数组的最后一个元素的cur存放第一个有数值的元素的下标,最后一个元素相当于头结点。

   其中数据结构的书上只有初始化,分配结点和回收结点的代码,如下:

void InitSLL(struct StaticLinkList *space){
   int i;
   for(i=0;i<MAXN-1;i++)  space[i].cur=i+1;
   space[MAXN-1].cur=0;
}

int MallocSLL(struct StaticLinkList *space){
   int i=space[0].cur;
   if(i){
      space[0].cur=space[i].cur;    //下标为0的cur始终指向有空闲的元素下标,而不是space[0].cur=i,指向下标为i的元素
   }
   return i;
}

void FreeSLL(int k,struct StaticLinkList *space){    //k是需要释放空间的下标,而非第k个元素
   space[k].cur=space[0].cur;
   space[0].cur=k;
}

   插入和删除操作,代码如下:

int insertSLL(int i,int val,struct StaticLinkList *space){
   if(i<1||i>ListLength(space)+1)  return 0;
   int j=MAXN-1;
   int k;
   int t=MallocSLL(space);
   if(j){
       space[t].data=val;
       for(k=1;k<=i-1;k++){
          j=space[j].cur;
       }
       space[t].cur=space[j].cur;
       space[j].cur=t;
       return 1;
   }
   return 0;
}

int deleteSLL(int i,struct StaticLinkList *space){
   if(i<1||i>ListLength(space))  return 0;
   int j=MAXN-1,k;
   for(k=1;k<=i-1;k++)  j=space[j].cur;
   k=space[j].cur;
   space[j].cur=space[k].cur;
   FreeSLL(k,space);
   return 1;
}

   另外还把数据结构书上的例子顺带实现了下,就是求(A-B)U(B-A),代码如下:

void difference(struct StaticLinkList *space){
   InitSLL(space);
   int s=MAXN-1,r,p,k;
   r=s;
   int m,n,i,j;
   printf("输入两个集合的长度:");
   scanf("%d%d",&m,&n);
   for(j=0;j<m;j++){
      i=MallocSLL(space);
      scanf("%d",&space[i].data);
      space[r].cur=i;
      r=i;
   }
   space[r].cur=0;
   display(space);
   for(i=0;i<n;i++){
      int tmp;
      scanf("%d",&tmp);
      p=MAXN-1;
      k=space[p].cur;
      while(k!=space[r].cur&&space[k].data!=tmp){
         p=k;
         k=space[k].cur;
      }
      if(k==space[r].cur){   //未出现重复,插入 
         j=MallocSLL(space);
         space[j].data=tmp;
         space[j].cur=space[r].cur;
         space[r].cur=j;
      }
      else{    //出现重复,删除 
         space[p].cur=space[k].cur;
         FreeSLL(k,space);
         if(r==k)  r=p;
      }
   }
   display(space);
}


总的代码如下:

#include <stdio.h>
#include <stdlib.h>
#define MAXN 1000  

struct StaticLinkList{
   int data;
   int cur;
};

void InitSLL(struct StaticLinkList *space){
   int i;
   for(i=0;i<MAXN-1;i++)  space[i].cur=i+1;
   space[MAXN-1].cur=0;
}

int MallocSLL(struct StaticLinkList *space){
   int i=space[0].cur;
   if(i){
      space[0].cur=space[i].cur;
   }
   return i;
}

void FreeSLL(int k,struct StaticLinkList *space){
   space[k].cur=space[0].cur;
   space[0].cur=k;
}

int ListLength(struct StaticLinkList *space){
    int i=space[MAXN-1].cur,j=0;
    while(i){
       i=space[i].cur;
       j++;        
    }
    return j;
}

void display(struct StaticLinkList *space){
     int i=space[MAXN-1].cur;
     while(i){
        printf("%d ",space[i].data);
        i=space[i].cur;
     }
     printf("\n");
}

int insertSLL(int i,int val,struct StaticLinkList *space){
   if(i<1||i>ListLength(space)+1)  return 0;
   int j=MAXN-1;
   int k;
   int t=MallocSLL(space);
   if(j){
       space[t].data=val;
       for(k=1;k<=i-1;k++){
          j=space[j].cur;
       }
       space[t].cur=space[j].cur;
       space[j].cur=t;
       return 1;
   }
   return 0;
}

int deleteSLL(int i,struct StaticLinkList *space){
   if(i<1||i>ListLength(space))  return 0;
   int j=MAXN-1,k;
   for(k=1;k<=i-1;k++)  j=space[j].cur;
   k=space[j].cur;
   space[j].cur=space[k].cur;
   FreeSLL(k,space);
   return 1;
}

void difference(struct StaticLinkList *space){
   InitSLL(space);
   int s=MAXN-1,r,p,k;
   r=s;
   int m,n,i,j;
   printf("输入两个集合的长度:");
   scanf("%d%d",&m,&n);
   for(j=0;j<m;j++){
      i=MallocSLL(space);
      scanf("%d",&space[i].data);
      space[r].cur=i;
      r=i;
   }
   space[r].cur=0;
   display(space);
   for(i=0;i<n;i++){
      int tmp;
      scanf("%d",&tmp);
      p=MAXN-1;
      k=space[p].cur;
      while(k!=space[r].cur&&space[k].data!=tmp){
         p=k;
         k=space[k].cur;
      }
      if(k==space[r].cur){   //未出现重复,插入 
         j=MallocSLL(space);
         space[j].data=tmp;
         space[j].cur=space[r].cur;
         space[r].cur=j;
      }
      else{    //出现重复,删除 
         space[p].cur=space[k].cur;
         FreeSLL(k,space);
         if(r==k)  r=p;
      }
   }
   display(space);
}

int main(int argc, char *argv[])
{
  struct StaticLinkList space[MAXN];
  difference(space);	
  return 0;
}
    说实话,这块用的太少,代码也是边看书边敲,我感觉这个就是属于那种JAVA API知道有这种函数存在,不会的时候,然后查一查就行了的知识点。我只是贴了代码,过程没有书上写的详细,也没有配上应该需要的图片,最好还是看书吧。


未完待续:下一节  链表算法四之循环链表


如果文章有什么错误或者有什么建议,欢迎提出,大家共同交流,一起进步

文章转载请注明出处,请尊重知识产权

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值