链表的学习笔记

简单说明

在实现链表类的数据结构时,可采用的方式一般有动态链表和静态链表的方式。

动态链表

动态链表的定义:

typedef struct LinkNode
{
	ElemType data;//data area
	LinkNode *link;//point area
}LNode,*LinkList ;

通过定义可以看出,动态链表的物理存储结构不是连续的,由单独的结点串联起来组成,使用时,可定义带头结点与不带头结点的动态链表,一般在使用时会引入一个指向链表结点的指针,通过这个指针对链表进行操作。
下面是对链表的一部分操作:

LinkList Create_Link()
{//创建带有头结点的动态链表
	LinkList p=(LinkList)malloc(sizeof(LNode));
	p->next=NULL;
	return p;
}
void Insert(LinkList &L,int i,int e)
{//将元素e插入到链表的位置i中
	LinkList NewNode=(LinkList)malloc(sizeof(LNode));
	NewNode->data=e;
	LinkList p=L;
	int cnt=1;
	if(i<0) return ERROR;//判断i是否合法
	while(p && cnt<i)
	{
		p=p->next;
		cnt++;
	}
	if(p||cnt<i) return ERROR;
	NewNode->next=p->next;
	p->next=NewNode;
}
int Length(LinkList &L)
{//返回量表长度
	int i;
	LinkList p=L;
	while(p)
	{
		p=p->next;
		i++;
	}
	return i;
}
int Locate(LinkList &L,int e)
{
	int i=1;
	LinkList p=L;
	while(p)
	{
		if(p->data==e) return i;
		p=p->next;
		i++;
	}
	if(!p) 
		return ERROR;
}
循环链表

在定义时只需使链表的尾结点的指针域指向链表的头结点,即可构成循环量表,可以在链表的任意位置循环,只是循环条件需要改变。

双向链表

对结点加入指向它的前驱的指针,可便于在某结点前插入新的结点。
定义方法:

typedef struct LinkNode
{
	ElemType data;//data area
	LinkNode *prior;
	LinkNode *next;//point area
}LNode,*LinkList;

静态链表

静态链表实际上是利用结构体数组来实现链表的思想,结构体数组由数据域以及用于存储相对位置的成员组成。
定义:

typedef struct SLinkList
{
	ElemType data;//存储数据
	int cur;//游标用于存储当前结点的后继结点的下标
}SLinkList[MAXSIZE],componend;

静态链表较特殊的一点是还存在一条将空闲位置连接起来的链表,一般将其称之为备用链表,备用链表的作用是回收数组中未使用或之前使用过(目前未使用)的存储空间,留待后期使用。备用链表的头结点一般为下标为零的结点,且备用链表的头结点通常不存储数据元素,数据链表的头结点一般使用下表为1的结点,可以置空,方便对其后继元素进行删除、插入新元素等操作。

#include<cstdio>
#include<iostream>
#define MAXSIZE 10
using namespace std;
typedef int ElemType;
typedef struct SLinkList
{
	ElemType data;
	int cur;
}componend,SLinkList[MAXSIZE];

//创建备用表
void Create_List(SLinkList &L)
{
    int i;
    for(i=0;i<MAXSIZE;i++)
    {
        L[i].cur=i+1;
    }
    L[i-1].cur=0;//将备用链表的最后一个结点指向头结点
}
nt Malloc_List(SLinkList &L)
{//取出备用链表的空余结点
    int i;
    i=L[0].cur;
    if(L[0].cur)
    {
        L[0].cur=L[i].cur;//备用链表的头节点游标指向下一个结点
    }
    return i;//返回的i作为可用节点的下标
}
void Display_List(SLinkList &L)
{
    int i=2,j=1;
    while(L[i].cur)
    {
        printf("elem[%d]=%d\n",j,L[i].data);
        j++;
        i=L[i].cur;//无法打印数据链表最后一个元素
    }
    printf("elem[%d]=%d",j,L[i].data);//打印数据链表最后一个元素
}
int Search_Elem(SLinkList &L,ElemType x)
{//搜索某元素在数据链表中的位置
    int i=2;
    while(L[i].cur)
    {
        if(x==L[i].data)
        {
            return i;
        }
        i=L[i].cur;
    }
    if(x==L[i].data)
    {
        return i;
    }
    return 0;
}

最好使用静态链表的表头代替上述操作中从i=2开始向后进行操作的代码,表头可以随删除插入等操作做出改变,可以令算法更为灵活。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值