参考《大话数据结构》:
环境:ubuntu16.04 vim
文件名称:staticlinklist.h staticlinklist:.c main.c Makefile(放到同一个目录下)
实现功能:链表节点分配、数据元素的插入和删除,链表长度计算
1.staticlinklist.h头文件
#ifndef __LINKLIST_HEAD__
#define __LINKLIST_HEAD__
#include <stdio.h>
#include <stdlib.h>
#define MAXSIZE 1000 //此处是设定的链表长度
#define OK 0
#define ERROR -1
#define TRUE 1
#define FALSE 0
typedef int ElemType;
typedef int Status;
/*线性表静态链表存储结构*/
typedef struct
{
ElemType data;
int cur; //Cursor游标,为0时表示无指向
}Component, StaticLinkList[MAXSIZE];
/*
*初始化数组状态
*space [IN, OUT]需要进行初始化的静态链表
*/
extern Status InitList(StaticLinkList space);
/*
*分配节点,若备用空间链表为空,则返回分配的节点下标,否则返回0
*space [IN, OUT]需要进行初始化的静态链表
*/
extern int MallocSLL(StaticLinkList space);
/*
*在静态链表L中的第i个数据元素之前插入新的数据元素e
*L [IN, OUT]需要进行操作的静态链表
*i [IN]第i个元素
*e [IN]待插入的新元素
*/
extern Status ListInsert(StaticLinkList L, int i, ElemType e);
/*
*删除静态链表L中的第i个数据元素
*L [IN, OUT]需要进行操作的静态链表
*i [IN]第i个元素
*/
extern Status ListDelete(StaticLinkList L, int i);
/*
*将空闲节点回收到备用链表
*space [IN, OUT]需要进行操作的静态链表
*k [IN]要删除元素的下标赋值给游标
*/
extern void FreeSLL(StaticLinkList space, int k);
/*
*返回静态链表中的元素个数
*L [IN, OUT]需要进行操作的静态链表
*/
extern int ListLength(StaticLinkList L);
#endif
2.staticlinklist.c文件
#include "staticlinklist.h"
/*初始化数组状态*/
Status InitList(StaticLinkList space)
{
int i;
for(i = 0; i < MAXSIZE - 1; i++)
{
space[i].cur = i + 1;
}
space[MAXSIZE - 1].cur = 0; //数组的最后一个元素的游标用来存放第一个插入元素的下标,在链表中相当于头节点
return OK;
}
/*静态链表的插入操作*/
/*1.分配节点*/
int MallocSLL(StaticLinkList space)
{
int i = space[0].cur; //当前数组的第一个元素中游标的值是一个空闲下标,做为返回值要备用。
if (space[0].cur)
{
space[0].cur = space[i].cur; //把下一个空闲的值赋值给第一个元素
}
return i;
}
/*2.插入数据元素*/
Status ListInsert(StaticLinkList L, int i, ElemType e)
{
int j, k, l;
k = MAXSIZE -1; //k是最后一个元素的下标
if (i < 1 || i > ListLength(L) + 1)
{
return ERROR;
}
j = MallocSLL(L); //获得空闲分量的小标
if (j)
{
L[j].data = e; //将数据赋值给此分量的data
for(l = 1; l <= i - 1; l++)
{
k = L[k].cur;
}
L[j].cur = L[k].cur; //把第i个元素之前的cur赋值给新元素的cur
L[k].cur = j;
return OK;
}
return ERROR;
}
/*删除操作*/
Status ListDelete(StaticLinkList L, int i)
{
int j, k;
if (i < 1 || i > ListLength(L))
{
return ERROR;
}
k = MAXSIZE - 1;
for (j = 1; j <= i - 1; j++)
{
k = L[k].cur;
}
j = L[k].cur;
L[k].cur = L[j].cur;
FreeSLL(L, j);
return OK;
}
/*回收节点到备用链表*/
void FreeSLL(StaticLinkList space, int k)
{
space[k].cur = space[0].cur; //把第一个元素的cur值赋值给要删除的分量cur
space[0].cur = k; //把要删除的分量小标赋值给第一个元素的cur
}
/*初始条件:静态链表L已存在。操作结果:返回L中数据元素个数*/
int ListLength(StaticLinkList L)
{
int j = 0;
int i = L[MAXSIZE - 1].cur;
while(i)
{
i = L[i].cur;
j++;
}
return j;
}
3.main.c文件
#include "staticlinklist.h"
int main()
{
Component L[MAXSIZE];
if (InitList(L))
{
printf("InitList failed!\n");
return ERROR;
}
int i = MallocSLL(L);
printf("i:%d\n", i);
if (ListInsert(L, 1, 3))
{
printf("ListInsert failed!\n");
return ERROR;
}
printf("L[2]:%d\n", L[2]);
if (ListInsert(L, 2, 4))
{
printf("ListInsert failed!\n");
return ERROR;
}
printf("L[3]:%d\n", L[3]);
if (ListDelete(L, 1))
{
printf("ListDelete failed!\n");
return ERROR;
}
printf("L[2]:%d\n", L[2]);
int l = ListLength(L);
printf("l:%d\n", l);
return OK;
}
4.Makefile文件
#Makefile for building programmings
OBJS=staticlinklist.o main.o
CC=gcc
CFLAGS=-Wall -g
TARGET=staticlinklist
TARGET:$(OBJS)
$(CC) $(OBJS) -o $(TARGET)
staticlinklist.o:staticlinklist.c staticlinklist.h
$(CC) $(CFLAGS) -c $< -o $@
main.o:main.c staticlinklist.h
$(CC) $(CFLAGS) -c $< -o $@
.PHONY:clean
clean:
rm *.o staticlinklist
5.执行结果