SLinkList(静态链表)

// stdafx.h : 标准系统包含文件的包含文件,
// 或是常用但不常更改的项目特定的包含文件
//

#define TRUE 1
#define FLASE 0
#define OK 1
#define ERROR 0
#define INFEASIBLE -1
#define OVERFLOW -2
#define NULL 0

typedef int Status;
typedef char ElemType;

#define MAXSIZE 1000 //链表的最大长度
typedef struct{
ElemType data;
int cur; //注意这里不是指针,而是类似游标的指示器
}component,SLinkList[MAXSIZE];

// 这是使用应用程序向导生成的 VC++
// 应用程序项目的主项目文件。
// 静态链表的表示和实现

#include "stdafx.h"
#include "stdio.h"
#include "malloc.h"
#include "stdlib.h" //需要exit所加头文件
#include "iostream.h"
#include <stdlib.h>

#using <mscorlib.dll>
#include <tchar.h>

using namespace System;

int LocateElem(SLinkList L,ElemType e){
// 这里和下面的space备用链表是没有关系的,就因为第0个和第1个分量的指向不同
// 在静态单链线性表L中查找第1个值为e的元素。
// 若找到,则返回它在L中的位序,否则返回0。
int i;
i=L[0].cur;
while(i && L[i].data==e)
i=L[i].cur;
return i;
} //LocateElem

Status DisplayList(SLinkList L){
// 输出静态链表L
int i,j;
i=L[1].cur;
j=1;
if(i==0)
cout<<"静态链表为空!"<<endl;
else
while(i){
cout<<"静态链表第"<<j<<"个结点是:"<<L[i].data<<endl;
i=L[i].cur;
j++;
}
return OK;
}

void InitSpace(SLinkList &space){
// 将一维数组space中各分量链成一个备用链表,space[0].cur为头指针
// “0”表示空指针
int i;
for(i=0;i<MAXSIZE-1;++i)
space[i].cur=i+1;
space[MAXSIZE-1].cur=0;
} //InitSpace

int Malloc_SL(SLinkList &space){
// 若备用空间链表非空,则返回分配的结点下标,否则返回0
// 即把备用链表的一个结点释放出来,但还没具体链接到静态
// 链表中。如果备用链表没有空间的话,返回0(因为此时space[0].cur=0)
int i;
i=space[0].cur;
if(space[0].cur)
space[0].cur=space[i].cur;
return i;
} //Malloc_SL

void Free_SL(SLinkList &space,int k){
// 将下标为k的空闲结点回收到备用链表。
// 即把静态链表中要删除的结点k释放出来,链接到备用链表中,
// 但静态链表中k结点的前驱和后继还没有处理。最后返回删除结点k.
space[k].cur=space[0].cur;
space[0].cur=k;
} //Free_SL

void difference(SLinkList &space,int &S){
// 依次输入集合A和B的元素,在一维数组space中建立表示集合(A-B)∪(B-A)
// 的静态链表,S为其头指针(静态链表的头指针)。假设备用空间足够大,
// space[0].cur为其头指针(备用链表的头指针)。
// S这个参数的存在是为了可以把头指针放在链表的任何位置,不局限于第一元素位置。
int r;
InitSpace(space); //初始化备用链表
S=Malloc_SL(space); //生成S的头结点,即静态链表的头指针
r=S; //r指向S的当前最后结点

int m,n;
cout<<"请您输入集合A的元素个数m=";
cin>>m;
cout<<endl;

int i,j;
for(j=1;j<=m;++j){ //建立集合A的链表
i=Malloc_SL(space); //分配结点,欲给静态链表
cin>>(space[i].data); //输入A的元素值
space[r].cur=i; //插入到静态链表的表尾
r=i; //r指向静态链表的表尾
}//for
space[r].cur=0; //静态链表的表尾指针为空
DisplayList(space); //输出A的元素
cout<<endl;

cout<<"B的元素个数n=";
cin>>n;
cout<<"下面请逐个输入B的元素"<<endl;

ElemType b;
int p,k;
for(j=1;j<=n;++j){ //依次输入B的元素,若不在当前表中,则插入,否则删除
cin>>b;
p=S;
k=space[S].cur; //k指向集合A的第一个结点
while(k!=space[r].cur && space[k].data!=b){ //在当前静态链表A中查找
p=k;
k=space[k].cur;
}//while
if(k==space[r].cur){ //当前表A中不存在该元素,插入在r所指结点之后,且r的位置不变。
i=Malloc_SL(space);
space[i].data=b;
space[i].cur=space[r].cur;
space[r].cur=i;
}//if
else{ //该元素已在表中,删除之
space[p].cur=space[k].cur;
Free_SL(space,k);
if(r==k) //若删除的是静态链表A中r所指结点,则需修改A的尾指针。
r=p;
}//else
}//for
}//difference

// 这是此应用程序的入口点
int _tmain(void)
{
// TODO: 请用您自己的代码替换下面的示例代码。
int S=1;
SLinkList space;
difference(space,S);
DisplayList(space);
return 0;
}


/*********************************************************************
这里的静态链表需要注意是的:
1、我现在把静态链表当成是用着的链表!!!不包括备用那些结点;
2、初始化时,把整个结构体数组初始化成一个备用链表;
3、静态链表和备用链表共用原来初始化的空间;
4、当tmain函数中的S=1时,初始化后的空间里,第0个元素和第1个元素的位置数据域
是空的。第0个用来指示备用链表第一个元素的位子,第1个则用来指示静态链表
第一个元素的位子,而且在这个思路中一直都是这样的!(当然你可以采取另一种
方式实现,在此不讨论);
5、Malloc_SL操作时,它所做的动作只是从备用链表释放一个结点,但释放出来的这
个结点还没具体链接到静态链表中;
6、Free_SL操作时,动作只是把静态链表中要删除的结点释放出来,链接到备用链表中,
但静态链表中k结点的前驱和后继还没有处理;
7、当你把B中的元素往A插时,B的元素一直顺着没改变以前的A尾插,而不是插在已经插
入元素的后面结点,比方说,依次插m,n两元素到A,那么先插m,就是:A-m;然后插
n,就是:A-n-m;
8、如果你老是想不明白,那么你就认认真真画图!画图,再画图,不要怕烦!你就明白了
*********************************************************************/

/*********************************************************************
附:

静态链表:由系统在内存中开辟了固定的、互不连续的存储单元,在程序执行过程中不可
能人为地再产生新的存储单元,它跟顺序结构没关系

静态链表其实就是用数组来描述的链表,一般是用于不设指针类型的语言,很少在C语
言中使用。不是顺序结构

difference(SLinkList &space,int &S)中的参数S=1时,有下面:
静态链表是这样的,在一个数组中有两个元素是不用的,分别是第0个元素和第1个元
素,第0个用来指示备用空间的第一个元素的位子,第1个则用来指示第一个链表元素
的位子,每当从链表中删除一个元素时.则让该元素成为备用链表的第一个结点,也即
让数组的第0个元素指向删除的结点,然后让删除的结点指向原来的备用链表的第1个
结点,插入的话类似
**********************************************************************/

转载于:https://www.cnblogs.com/yujun543/archive/2012/09/11/2680742.html

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值