线性表之单链表


单链表存储结构

typedef struct Node
{
	int data;
	struct Node *next;
}Node;
typedef struct Node* LinkList;

节点由存放数据元素的数据域和存放后继节点地址的指针域组成

在这里插入图片描述


一、单链表的创建

头插法

目的:创建长度为n的链表例如:7->6->5->4->3->2->1->NULL
实现:

①创建L为头节点:数据域为空,指针域指向NULL作为头指针
②添加n个节点:创建结点指针p,每次创建申请空间生成一个新的节点
利用指针操作数据域的赋值。从头指针后开始插入,每次插入的结点为链表的第一个结点

void CreateListHead(LinkList &L,int n)
{
	LinkList p;
	L=(LinkList)malloc(sizeof(Node));
	(L)->next=NULL;
	for (int i = 0; i < n; i++)
	{
		p=(LinkList)malloc(sizeof(Node));
		p->data=i+1;
		p->next=(L)->next;
		(L)->next=p;
	}
}
因为每次按“顺序”插入的是第一个节点,所以链表数据是“倒序”的

尾插法

目的:创建长度为n的链表例如:1->2->3->4->5->6->7->8->9->10->NULL
实现:

①创建L为头节点,赋给指针r,指针r作为游标
②添加n个节点:创建结点指针p,每次创建申请空间生成一个新的节点
利用指针操作数据域的赋值。从头指针后开始插入,每次插入的结点为链表的最后一个结点
③每次插入后把新插入的结点赋给游标r,标记最后一个结点的位置
④最后将r指向NULL作为结束

void CreateListTail(LinkList &L,int n)
{
	LinkList p,r;
	L=(LinkList)malloc(sizeof(Node));
	r=L;
	for (int i = 0; i < n; i++)
	{
		p=(LinkList)malloc(sizeof(Node));
		p->data=i+1;
		r->next=p;
		r=p;
	}
	r->next=NULL;
}
因为每次按“顺序”插入的是最后一个节点,所以链表数据也是“顺序”的

二、单链表的读取

功能:读取链表中第i个数据的值
实现:
①创建p指向第一个结点,利用j作为结点的下标
②向后移动p,直到找到所在结点,若j>i或p为空说明链表没有第i个元素
③得到第i个数据的值

void GetElem(LinkList &L,int i)
{
	int j=1;
	LinkList p=L->next;
	while (p&&j<i)
	{
		p=p->next;
		++j;
	}
	if (!p||j>i)
	{
		cout<<"have not found this element!"<<endl;
		return ;
	}
	int e=p->data;
	cout<<e<<endl;
	return ;
}

三、单链表的插入

功能:将数据e插入到链表第i个数据之后
实现:
①创建p指向第一个结点,利用j作为结点的下标
②向后移动p,直到找到所在结点,若j>i或p为空说明链表没有第i个元素
③生成新的节点add,将e赋值给add的数据域,先让add指向p的下一个节点,再让p指向add

void ListInsertAft(LinkList &L,int i,int e)
{
	LinkList p=L->next;
	int j=1;
	while (p&&j<i)
	{
		p=p->next;
		j++;
	}
	if(!p||j>i)
	{
		cout<<"结点不存在!"<<endl;
		return ;
	}
	LinkList add=(LinkList)malloc(sizeof(Node));
	add->data=e;
	add->next=p->next;
	p->next=add;
	return ;
}
必须先让add指向p的下一个节点,再让p指向add。

若先让p指向add,则p的下一个节点就是add,add没办法指向原来p后的节点,相当于链表“断了”。


四、单链表的删除

功能:删除单链表中第i个元素
实现:
①创建p为头指针,利用j作为标记,j比p的下标大1
②向后移动p,直到找到所删除结点前一个节点,若j>i或p->next为空说明链表没有第i个元素
③创建q指向p之后的第一个结点(所删除的结点),再使p指向的下一个节点为q的下一个节点,即跳过q这个节点
④释放结点q的内存

void ListDelete(LinkList &L,int i)
{
	LinkList p=L,q;
	int j=1;
	while (p->next&&j<i)
	{
		p=p->next;
		j++;
	}
	if(!(p->next)||j>i) 
	{
			cout<<"结点不存在!"<<endl;
			return ;
	}
	q=p->next;
	p->next=q->next;
	cout<<q->data<<endl;
	free(q);
	return ;
}

五、单链表的整表删除

功能:删除整个链表
实现:
①创建p指向第一个结点,将p赋值给q
②先释放掉q的内存,再向后移动p,直到表尾
③使头指针L指向NULL,表中不再有数据元素

void ClearList(LinkList &L)
{
	LinkList p,q;
	p=L->next;
	while (p!=NULL)
	{
		q=p;
		p=p->next;
		free(q);
	}
	L->next=NULL;
	cout<<"删除成功!"<<endl;
}

六、显示链表中的数据

功能:显示所有数据
实现:创建p指向第一个结点,每次向后移动输出数据即可

void show(LinkList &L)
{
	LinkList p=L->next;
	while (p!=NULL)
	{
		printf("%d->",p->data);
		p=p->next;
	}
	cout<<"NULL"<<endl;
	return ;
}

总结

本篇介绍了对单链表的创建、插入、删除等操作。使用c++的指针对链式存储结构进行操作十分灵活,有牵一发而动全身的效果。

测试代码及运行实例

int main()
{
	LinkList cr,me;
	CreateListHead(cr,7);
	show(cr);
	CreateListTail(me,10);
	show(me);
	GetElem(cr,7);
	GetElem(me,10);
	ListInsertAft(cr,7,50);
	show(cr);
	ListDelete(cr,1);
	show(cr);
	ClearList(cr);
	show(cr);
	return 0;
}

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

新西兰做的饭

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值