C语言静态链表

在C语言中用指针可以实现线性单链表,而有些语言不支持指针,我们可以利用两个并行的数组或者结构体数组来模拟指针,这样子的链表称之为静态链表。

在我看来,静态链表的优点就是,虽然没有指针,但通过游标操作,同样实现了指针具有的一些优点,比如插入删除操作不需要像顺序存储结构那样移动很多的元素。

它的缺点就是在不知道需要多少存储空间时,预先分配了一个很大的数组,这样还是比较浪费的。静态链表主要是给没有指针的高级语言设计的,这种思想非常巧妙,值得我们学习。

下面,我给出了C语言下的实现方法,并给出了基本的操作函数,以及针对每种操作,都进行了打印输出的验证。

/*******************************************************************/
//描述:使用结构体数组静态链表的创建,插入,删除等基本操作的函数,以及对这些操作进行验证
//时间:2017.12.29  11:00
//作者:Liu ZhenHua
//*****************************************************************/
#include 
#include 
#define MAXSIZE 1000
#define OK 1
#define TRUE 1
#define FALSE 0
#define ERROR 0

typedef char ElemType;
typedef int Status;

typedef struct{
    ElemType data;
    int cur;
}Component,StaticLinkList[MAXSIZE];

Status InitList(StaticLinkList space);      //初始化静态链表
int malloc_SLL(StaticLinkList L);           //分配新的空间
int listLength(StaticLinkList sl);          //读取链表长度,即链表存储有几个数据
Status GetElem(StaticLinkList L,int i,ElemType *e);
void printStaticLinkList(StaticLinkList L); //顺序打印链表
                                            //在第i个元素之前插入元素e
Status InsertElem(StaticLinkList L,int i,ElemType e);
                                            //删除掉第i个元素
Status DeleteElem(StaticLinkList L,int i,ElemType *e);
void printSL(void);                         //打印一行分割线
int main()
{
    char cv = 'a';int listlen;
    StaticLinkList sl;
    char tempchar,*cp;cp = &tempchar;
    if(InitList(sl))printf("静态链表创建成功!\n");
    //初始化后生成一个包含4个元素的新链表
    sl[1].data=cv;sl[2].data=cv+1;sl[3].data=cv+2;sl[4].data=cv+3;sl[4].data=cv+3;
    sl[0].cur=5;sl[4].cur=0;sl[MAXSIZE-1].cur=1;
    listlen = listLength(sl);
    printf("链表长度为: %d\n",listlen);
    printStaticLinkList(sl);
    printSL();
    if(GetElem(sl,3,cp)){
        printf("取出第三个元素为:%c\n",*cp);
    }else{
        printf("取出元素失败!\n");
    }

    printSL();                      //插入操作
    if(InsertElem(sl,2,'e'))printf("在第二个插入元素'e'之后\n");
    listlen = listLength(sl);
    printf("链表长度为: %d\n",listlen);
    printStaticLinkList(sl);
    printSL();                      //删除操作
    if(DeleteElem(sl,3,cp))printf("删除第三个元素成功!\n");
    listlen = listLength(sl);
    printf("链表长度为: %d\n",listlen);
    printStaticLinkList(sl);
    return 0;
}
/**********************************************/
//函数名:InitList
//描述  : 初始化静态链表
//参数  :结构体数组space
//返回值:状态值
//作者  :LiuZhenHua
/**********************************************/
Status InitList(StaticLinkList space){
    int i;
    for(i=0;i MAXSIZE || i<1 || L[k].cur==0){
        return ERROR;               //插入位置不对或者链表为空链表
    }
    for(j = 0; j < i-1; j++){       //循环,得到插入位置左邻元素的数组下标
        k = L[k].cur;
    }

    m = malloc_SLL(L);              //开辟一个新空间,并返回要插
    L[m].data = e;                  //将数据存入元素的数据域
    L[m].cur = L[k].cur;            //更换元素下标
    L[k].cur = m;
    return OK;
}
/**********************************************/
//函数名: DeleteElem
//描述  : 在第i个元素前删除元素e
//参数  :结构体数组名,位置i,返回元素指针*e
//返回值:状态值
//作者  :LiuZhenHua
/**********************************************/
Status DeleteElem(StaticLinkList L,int i,ElemType *e){
    int j,k,n1,n2;
    k = MAXSIZE - 1;
    if(i > MAXSIZE || i<1 || L[k].cur==0){
        return ERROR;               //删除位置不对或者链表为空链表
    }
    for(j = 0; j < i-1; j++){       //循环,得到插入位置左邻元素的数组下标
        k = L[k].cur;
    }
    n1 = k;
    k = L[k].cur;
    *e = L[k].data;
    n2 = L[k].cur;
    L[n1].cur = n2;
    L[k].cur=L[0].cur;              //交换元素的下标,更换空链表
    L[0].cur=k;
    return OK;
}
/**********************************************/
//函数名: printSL
//描述  : 打印一行分割线Print Split Line
//参数  :结无
//返回值:无
//作者  :LiuZhenHua
/**********************************************/
void printSL(void){
    int i;
    for(i = 0; i < 20; i++){
        printf("-");
    }
    printf("\n");
}
/**********************************************/
//函数名: GetElem
//描述  : 取出在第i个位置的元素e
//参数  :结构体数组名,位置i,返回元素指针*e
//返回值:状态值
//作者  :LiuZhenHua
/**********************************************/
Status GetElem(StaticLinkList L,int i,ElemType *e){
     int j,k;
     k = MAXSIZE - 1;                //最后一个元素的数组下标
      if(i > MAXSIZE || i<1 || L[k].cur==0){
        return ERROR;               //插入位置不对或者链表为空链表
    }
     for(j = 0; j < i; j++){       //循环,得到插入取出元素的数组下标
        k = L[k].cur;
    }
    *e = L[k].data;
    return OK;
}


你可能感兴趣的:(数据结构与算法分析)