链表的游标实现

概念引入

在最开始的学习中,我们实现链表都需要依靠指针来连接链表的各个节点,但是,在一些语言中是不支持指针的,那么,在不使用指针的情况下,我们就无法实现链表了吗?当然不是,其实还有另一种链表的实现方式——游标实现!

思路分析

那么如果想不使用指针,我们必须了解指针在链表中的作用,我们来想一下,以前在写链表时,我们在那些地方用到了指针,首先当然是在链表的节点定义中,用指针来指向下一个节点,那么我们要想办法用一个东西代替它,我们发现,其实数组的下标完全可以充当指针,只要有了数组下标,就可以轻而易举的知道对应的元素了。以此为基础,就可以想到,构造一个结构体数组,里面有两个变量,一个存放元素的值,另一个存放下一个节点的下标值,充当指针作用。然后,我们要考虑分配和释放内存单元的问题,首先,我们可以选定一个节点作为头节点,让她一直指向下一个空的数组元素单元,由于数组的大小是有限的,所以我们还需要考虑让删除的元素重新利用。只要知道了这些,那么后面的具体实现其实就很简单了,与以前的写法相似。还要注意的的是,数组是需要我们自己先进性初始化的,必须让他们一开始就有一个指向顺序,如果不初始化就无法正确的分配新的空间,这一步在下面的main函数中给出。

具体实现

具体实现如下所示

//测试函数与初始化
int main()
{
    int head=1;		//链表头节点
    cursor[0].next=2;//cursor[0]游标头节点,指向下一个空闲空间
    cursor[head].next=0;//0代表NULL
    int i;
    for(i=2;i<9;i++){	//游标数组初始化
        cursor[i].next=i+1;
    }
    Insert2(1,head,3);
    Insert2(1,2,4);
    Insert2(1,3,5);
    Delect2(1,5);
    Print2(head);
    return 0;
}
//打印链表
void Print2(int head){
    int p=cursor[head].next;
    while(p!=0)
    {
        printf("%d",cursor[p].x);
        p=cursor[p].next;
    }
    }
//节点定义
struct Node2{
int x;	//存放元素
int next;//存放下一个节点下标
};
struct Node2 cursor[10];				//游标数组
//释放空间
void ffree(int s){
    cursor[s].next=cursor[0].next;	//让要释放的节点放到空闲节点和头节点之间,  
    cursor[0].next=s;				//下次再申请空间是就是用这个被释放的节点
    }
//分配空间
int mmalloc(){
    int p=cursor[0].next;			//头节点的下一个元素就是空余的空间
    cursor[0].next=cursor[p].next;
    return p;
    }
//插入元素
void Insert2(int head,int p,int x){
    int p1=mmalloc();
    if(p1!=0){	//如果p1为0,则表示数组空间已满
    cursor[p1].x=x;
    cursor[p1].next=cursor[p].next;
    cursor[p].next=p1;
    }
    }
//查找元素
int Find2(int head,int x){
    int p=cursor[head].next;	//循环查找,也可直接用下面一个函数			
    while(p!=0&&cursor[p].x!=x)//FindPrevious2()间接查找
        p=cursor[p].next;
    return p;
    }
int Findprevious2(int head,int x){
    int p=cursor[head].next;
    if(cursor[p].x==x)	//如果是第一个元素,则返回头节点
        return head;
    if(p!=0)
    while(cursor[p].next!=0&&cursor[cursor[p].next].x!=x)//如果下标为p的元素下一个元素为空,或者
        p=cursor[p].next;								//下一个元素即为所需查找的元素,则结束
        												//循环
    return p;
    }
//原理与普通链表类似,只是写法稍微改一下
//删除元素
void Delect2(int l,int x){
    int p=Find2(l,x);
    if(p!=0){
    int p2=Findprevious2(l,x);
    cursor[p2].next=cursor[p].next;
    ffree(p);
    }
    }
  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值