链表算法三之静态链表

来源:互联网 发布:朝鲜和韩国知乎 编辑:程序博客网 时间:2024/05/21 21:39

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

   需要注意的是数组第一个和最后一个元素不存数据,其中下标为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 0
原创粉丝点击