静态链表
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了静态链表相关的知识,希望对你有一定的参考价值。
一、为何需要静态链表:
c有指针可以很容易地操作内存中的地址和数据,java、c#等面向对象语言没有指正,但他们启用了对象。但是有些早起编程语言,如Basic、Fortran等没有指针这时就需要静态链表。
二、静态链表是什么:
静态链表是借助数组来描述县新表的列式存储结构。他定义的时候也有数据域data和指针域next,这里的指针其实就是他存储的元素所在数组中的下标。如图:
(此图片来自互联网网友)
按图中所示,非空闲链表为
通过保存下一个元素的数组下标依次把元素链接起来
三、链表总结:
一个数组逻辑分成两部分,他们都是通过指针来连接的。
空闲链表由空闲头结点来链接起来,空闲链表最后一个结点的next一般为0,
非空闲链表由非空闲头结点连接起来,由于每次申请都是从空闲头结点下一个位置申请空闲节点,所以非空闲头结点是数组下标为1的节点
在链表里保存了元素之后,就把链表的最后一个结点(list[MaxSize-1].next)的指针域修改为1,也就是保存非空链表的头结点。
四、实战
- 基本的函数
- 静态链表定义
#define MaxSize 50 typedef struct{ int data; int next;//游标或者指针域 }List;
- 初始化静态空闲链表
void init_sl(List list[]) { int i; for(i=0;i<MaxSize;i++) { list[i].next=i+1;//因为都没有赋值,所以直接指向下一个 } list[MaxSize-1].next=0; }
- 静态链表长度
int ListLength(List list[]) { int j=0; int i=list[MaxSize-1].next; while(i)//当i<=0时停止 { i=list[i].next; j++; } return j; }
- 申请分配空闲结点
思路:分配结点时都是分配的空闲链表头结点后第一个结点,因为第一个几点被分配,所以要调整头结点,让他指向下一个空闲结点(也就是原来的第二个空闲结点),最后把申请的结点数组下标返回
int malloc_sl(List list[]) { int i=list[0].next;//取头结点后的第一个空闲结点 if(i) { list[0].next=list[i].next;//调整空闲链表头结点的指针域 } return i;//返回申请到空闲结点数组下标 }
- 在第i个元素前插入新元素
思路:先找到i的前一个元素,在让新申请的next指向i
bool ListInsert(List list[],int i,int e) { int j,k,l; k=MaxSize-1; if(i<1||i>ListLength(list)+1) //判断位置是否非法 return false; j=malloc_sl(list);//申请一个空闲结点 if(j) { list[j].data=e; for(j=1;j<=i-1;j++) { k=list[k].next;//找到第i个元素之前的元素 } list[j].next=list[k].next;//把第i个元素之前next赋值给新申请的next(也就想当于让j指向i) list[k].next=j;//在让i的前一个元素的next指向j return true; } return false; }
- 释放内存
void Free_SSL(List list[],int k) { list[k].next=list[0].next; list[0].next=k; }
- 静态链表删除操作
bool ListDelet(List list[],int i) { int j,k; if(i<1||i>ListLength(list)+1) return false; else { k=MaxSize-1; for(j=1;j<i;j++) { k=list[k].next; }//找到i的前一个元素 j=list[k].next;//让j保存第一个元素的下标 list[k].next=list[j].next; return true; } }
以上是关于静态链表的主要内容,如果未能解决你的问题,请参考以下文章