线性表的链式存储结构——链表及其操作(创建,查找,插入,输出,删除)

1.单链表的建立

1.1头插法

1)从一个空表开始,创建一个头结点。

2)依次读取数组a中的元素,生成新节点。

3)将新节点插入到当前链表的表头上,直到结束为止,插入过程如下图所示。

在这里插入图片描述

首先定义单链表节点类型,LinkNode类型声明如下:

typedef struct LNode
{
	int data;
	struct LNode *next;//存储后继节点位置的指针域,用next表示 
}LinkNode;

头插法代码如下,由数组元素a创建单链表L

void CreatListF(LinkNode * &L,int a[],int n) //头插法建立单链表 
{
	LinkNode *s;
	L=(LinkNode *)malloc(sizeof(LinkNode));  //创建头结点并将其next域置位NULL 
	L->next=NULL;
	for(int i=0;i<n;i++)//循环建立数据节点s
	{
		s=(LinkNode *)malloc(sizeof(LinkNode)); 
		s->data=a[i];
		s->next=L->next; //将s节点插入到原首节点之前,头结点之后 
		L->next=s;
	}
}

1.2尾插法

1)从一个空表开始,创建一个头结点。

2)依次读取数组a中的元素,生成新节点。

3)将新节点插入到当前链表的表尾上,直到结束为止,插入过程如下图所示。
在这里插入图片描述
尾插法需要将新节点插入到当前链表的表尾上,为此需要增加一个尾指针r,

使其始终指向当前链表的尾节点,最后需要将尾节点的next域置为NULL。

void CreatListR(LinkNode * &L,int a[],int n)//尾插法建立单链表
{
	LinkNode *s,*r;
	L=(LinkNode *)malloc(sizeof(LinkNode));
	r=L;							//r始终指向尾节点,初始时指向头结点 
	for(int i=0;i<n;i++)
	{
		s=(LinkNode *)malloc(sizeof(LinkNode));
		s->data=a[i];				//将s插入到r之后 
		r->next=s;
		r=s;						//r指向插入的新节点(尾节点) 
	}
	r->next=NULL;					//尾节点的next域置为NULL 
}

2.链表基本操作

1)初始化链表

void InitList(LinkNode * &L)//初始化线性表 
{
	L=(LinkNode *)malloc(sizeof(LinkNode));//创建一个空的单链表 
	L->next=NULL;
}

2)销毁链表

该运算会释放L所占的内存空间,其过程是让pre,p指向两个相邻的节点,

当p不为空时循环,释放pre,然后p,pre同步后移一个节点,如下图所示。在这里插入图片描述
实现销毁操作如下

void DestoryList(LinkNode * &L)//销毁线性表 
{
	LinkNode *pre=L,*p=L->next; //pre指向p的前驱节点 
	while(p!=NULL) //扫描单链表 
	{
		free(pre); //释放pre节点 
		pre=p;     //pre,p同步后移一个节点 
		p=pre->next;
	}
}

3)判断链表是否为空

bool ListEmpty(LinkNode *L)//判断链表是否为空 
{
	return(L->next==NULL);
}

4)求链表的长度

由于链表没有存放节点个数的信息,所以需要遍历链表,用n来记录节点个数

int ListLength(LinkNode *L)//求链表长度 
{
	int n=0;
	LinkNode *p=L;//p指向头结点,n置为0 
	while(p->next!=NULL)
	{
		n++;
		p=p->next;
	}
	return n;
}

5)输出链表

void DispList(LinkNode *L)
{
	LinkNode *p=L->next;//p指向首节点 
	while(p!=NULL)
	{
		printf("%d ",p->data);
		p=p->next; //p移向下一节点 
	}
	printf("\n");
}

6)查找链表第i个元素值

从头结点开始遍历,用 j 来累计遍历过的节点个数,直到第i个节点,将元素值赋给tmp。

bool GetElem(LinkNode * &L,int i,int &tmp)//求链表第i个元素值 
{
	int j=0;
	LinkNode *p=L;//p指向头结点
	if(i<=0)
		return false;
	while(j<i&&p!=NULL)//找到第i个节点
	{
		j++;
		p=p->next;
	}
	if(p==NULL)
		return false;
	else
	{
		tmp=p->data;
		return true;//提取值成功,返回true
	}
} 

6)插入数据节点

遍历单链表找到第 i-1 个节点 p ,将元素值为e的节点*s插入到其后
在这里插入图片描述
实现如下:

bool ListInsert(LinkNode * &L,int i,int e)//插入数据元素 
{
	int j=0;
	LinkNode *p=L,*s;
	while(j<i-1&&p!=NULL)//找到第i-1个节点 
	{
		j++;
		p=p->next;
	}
	if(p==NULL)
		return false;
	else
	{
		s=(LinkNode *)malloc(sizeof(LinkNode));  //将s节点插入 
		s->data=e;
		s->next=p->next;
		p->next=s;
		return true;
	}
}

7)删除数据节点

遍历单链表找到第 i-1 个节点 p,若存在这样的节点也存在后继节点,则删除该后继节点
在这里插入图片描述
实现如下:

bool ListDelete(LinkNode * &L,int i)
{
	int j=0;
	LinkNode *p=L,*q;
	while(j<i-1&&p!=NULL)//找到第i-1个节点 
	{
		j++;
		p=p->next;
	}
	if(p==NULL)
		return false;
	else
	{
		q=p->next;
		if(q==NULL)
			return false;
		p->next=q->next;//删除q节点 
		free(q);
		return true;
	}
} 
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值