静态链表(用数组不用指针)
#define maxsize 1000 //假设数组最大长度为1000
typedef struct
{
ElemType data;
int cur; //游标
}Component,StaticLinkList[maxsize];
一.数组第一个元素和最后一个元素不存数据
1.第一个元素存放备用链表(空闲位置)的一个结点的下标
2.最后一个元素存放第一个有数值插入的下标
二.静态链表初始化
void InitList(StaticLinkList space)//space为数组
{
int i;
for(i=0;i<maxsize;i++){
space[i].cur=i+1;
}
space[maxsize-1].cur=0;//目前静态链表为空,最后一个元素的cur为0
}
三.辨明数组中哪些未被使用,要知道哪个位置(下标)的函数
int Malloc_SLL(StaticLinkList space) //返回新结点下标
{
int i=space[0].cur; //当前数组第一个元素的cur存的值就是要返回的第一个备用空闲的下标
if(space[0].cur){ //看作接替者,拿出来一个用,下一个要顶替被用的位置
space[0].cur=space[i].cur;
}
return i; //返回新结点下标
}
四.插入操作(总结1.将要插入元素先放在空闲位置的第一个位置 2.插入位置前一个元素的游标改为此时插入元素在空闲位置的下标 3.插入元素游标改为插入位置下一个元素的下标)
void ListInsert(StaticLinkList L,int i,int e) //插入操作
{
int j,k,l;
k=maxsize-1; //k首先是最后一个元素的下标
if(i<1||i>ListLength(L)+1){ //简单判断,因为函数类型是void,所以这里直接return;
return;
}
j=Malloc_SLL(L); //获得空闲分量的下标
if(j){ //开始插入
L[j].data=e; //将数据赋值给data
for(l=1;l<=i-1;l++){ //改动游标和下标过程,无法理解的话可以直接把i=3代数据去理解
k=L[k].cur;
}
L[j].cur=L[k].cur;
L[k].cur=j;
}
}
五.删除操作
void Free_SLL(StaticLinkList space,int k)//删除操作的必要函数
{
space[k].cur=space[0].cur;//把第一个元素cur的值给要删除的cur
space[0].cur=k;//把要删除的cur的下标给第一个元素,将来优先考虑的插入位置
}
void ListDelete(StaticLinkList L,int i) //删除操作
{
int j,k;
if(i<1||i>ListLength(L)){ //判断
return;
}
K=maxsize-1;
for(j=1;j<=i-1;j++){//可带入具体数据验证
k=L[k].cur;
}
L[k].cur=L[j].cur;
Free_SLL(L,j); //删除操作的重要步骤
}
六.静态链表长度函数
int ListLength(StaticLinkList L) //长度函数(求得此链表的长度)
{
int j=0;
int i=L[maxsize-1].cur;
while(i){
i=L[i].cur;
j++;
}
return j;
}
七.链表输出函数
void print(StaticLinkList L) //输出链表操作
{
int k=L[maxsize-1].cur;
while(k){
printf("%d ",L[k].data);
k=L[k].cur;
}
printf("\n");
}
八.静态链表具体插入操作代码
/*************************************************************************
> File Name:静态链表.c
> Author: geeker
> Mail: 932834897@qq.com
> Created Time: 2017年02月02日 星期四 20时15分10秒
************************************************************************/
#include<stdio.h>
#define OK 1
#define ERROR 0
#define maxsize 1000
typedef int Status;
typedef struct
{
int data;
int cur;
}Component,StaticLinkList[maxsize];
int ListLength(StaticLinkList L) //长度函数(求得此链表的长度)
{
int j=0;
int i=L[maxsize-1].cur;
while(i){
i=L[i].cur;
j++;
}
return j;
}
void InitList(StaticLinkList space) //链表初始化 (space是数组)
{
int i;
for(i=0;i<maxsize-1;i++){
space[i].cur=i+1;
}
space[maxsize-1].cur=0; //目前静态链表为空,最后一个元素的cur为0
}
void ListInsert(StaticLinkList L,int i,int e) //插入操作
{
int j,k,l;
k=maxsize-1; //k首先是最后一个元素的下标
if(i<1||i>ListLength(L)+1){ //简单判断,因为函数类型是void,所以这里直接return;
return;
}
j=Malloc_SLL(L); //获得空闲分量的下标
if(j){ //开始插入
L[j].data=e; //将数据赋值给data
for(l=1;l<=i-1;l++){ //改动游标和下标过程,无法理解的话可以直接把i=3代数据去理解
k=L[k].cur;
}
L[j].cur=L[k].cur;
L[k].cur=j;
}
}
void print(StaticLinkList L) //输出链表操作
{
int k=L[maxsize-1].cur;
while(k){
printf("%d ",L[k].data);
k=L[k].cur;
}
printf("\n");
}
int main()
{
StaticLinkList L;//建立链表L
InitList(L);//链表初始化
for(int i=0;i<8;i++){
ListInsert(L,1,i); //将1-8数字插入到链表中(其实相当于给链表赋值)注意从1开始
}
print(L);//输出链表
ListInsert(L,3,22);//在第三个位置插入22这个数
print(L);
return 0;
}
九.个人学完线性表的总结
除了博中提到过的一些表当然还有循环链表、双向链表等,这些以后也会慢慢接触到,总结起来现在学了顺序结构,单链表,静态链表还有具体操作,每一种都有各自的特点,比如静态链表插入删除操作只需改动游标而不需要移动元素,单链表只需改动指针指向而且单链表表长也可以根据自己的需要去开辟空间,但有时候单链表也会有效率的问题,顺序表的效率有时候挺高的,只可惜要移动元素,反正各有各的优点缺点嘛,静态链表以后也会经常用到没有指针的语言里。最后发张线性表的结构图