线性表——单链表的C语言源码实现

单链表即线性表的链式存储结构,也叫线性链表。其特点是用一组任意的存储单元来保存数据,链表的每个节点分为数据域和指针域。数据域用来保存数据信息,指针域用来指示下一个节点的存储单元地址。

从上可以看出:

1)单链表有一个头结点,要查找某个节点时从该节点出发查找。

2)要删除某个位置的节点,可以通过修改该节点的前驱节点的指针域和该节点的指针域相同,这样其前驱节点将会直接指向下一个节点(当然,删除之后要调用free函数来释放)

3)要在某个位置插入一个节点,同删除,只需新建一个节点元素,然后将要插入位置的前驱节点的指针域指向新节点元素的地址,并将该节点的指针域指向插入位置的节点。

定义单链表的结构为:

#define ElemType int
typedef struct LNode{
	ElemType data;									//单链表每个节点保存的数据	即数据域
	struct LNode *next;								//单链表的指向下一个节点的指针	即指针域
}LNode,Linklist;

分别实现链表的创建,插入,删除,查找

创建:

/*
	函数名:Linklist_creat
	函数功能:建立带表头节点L的单链表
	函数返回:返回表头节点的地址
*/
Linklist* Linklist_creat(ElemType e)
{
	Linklist *L;
	L=(LNode*)malloc(sizeof(LNode));				//为表头节点分配内存
	L->next=NULL;									//将头结点的指针域赋值为null
	L->data=e;										//头结点指针域赋值
	return L;
} 

插入代码:

/*
	函数名: Linklist_insert
	函数功能:在单链表的某个位置插入一个元素
	函数返回:返回插入的结果EROOR失败,OK成功,
*/
int Linklist_insert(Linklist *L, int i,ElemType e)
{
	Linklist *p = L;
	for(;i>0&&p->next!=NULL;i--)
	{	
		p=p->next;									//移动头指针指向第i个节点
	}
	if(p->next==NULL&&i!=0)							//即L已经指向最后一个节点而位置还没调整到第i个节点,则i不合法
	{
		return ERROR;
	}
	else if(p->next==NULL&&i==0)					//即L已经指向最后一个节点而位置刚好调整到第i个节点,即在链表的尾部添加一个节点
	{
		LNode* NewNode=(LNode*)malloc(sizeof(LNode));
		NewNode->data=e;
		NewNode->next=NULL;
		p->next=NewNode;
		return OK;
	}
	else if(p->next!=NULL&&i==0)					//即向两个节点中插入一个新的节点
	{
		LNode* NewNode=(LNode*)malloc(sizeof(LNode));
		NewNode->data=e;
		NewNode->next=p->next;
		p->next=NewNode;
		return OK;
	}
}

删除:

/*
函数名: Linklist_delete
函数功能:删除单链表第i个位置的元素
函数返回:若成功删除,返回删除元素的值,否则返回ERROR
*/
ElemType Linklist_delete(Linklist *L, int i)
{
	Linklist *p = L;
	ElemType e;
	for (i=i-2; i>0 && p->next != NULL; i--)		//这里的i-2~~~~~如要删除第2个节点,p应当指向第一个节点,故p移动一次,则条件为(i-1)-1
	{
		p = p->next;								//移动指针指向第i个节点的前一个节点
	}
	if (p->next == NULL&&i != 0)					//即L已经指向最后一个节点而位置还没调整到第i个节点,则i不合法
	{
		exit(0);
	}
	else if (p->next == NULL&&i == 0)				//即L已经指向最后一个节点而位置刚好调整到第i个节点的前一个节点,即删除链表尾部的一个节点
	{		
		e = p->next->data;
		free(p->next);
		p->next = NULL;
		return e;
	}
	else if (p->next != NULL&&i == 0)				//即删除两个节点中的一个节点
	{
		Linklist *tmp = p->next;
		e = p->next->data;
		p->next = p->next->next;					//调整已删除节点的前驱节点的指针域
		free(tmp);									//释放要删除的节点的存储空间
		return e;
	}
}

查找:

/*
函数名:Linklist_GetElm
函数功能:得到单链表中某个位置的元素,并将其返回
函数返回:返回单链表某个位置的值
*/
ElemType Linklist_GetElm(Linklist *L, int i)		//得到单链表中某个位置的元素,并将其返回
{
	Linklist *p = L;
	for (i=i-1; i>0 && p->next != NULL; i--)		//要得到第i个位置的数据,需要头结点移动i-1次
	{
		p = p->next;//移动头指针指向第i个节点
	}
	return  p->data;

}



猜你喜欢

转载自blog.csdn.net/codeeror/article/details/80169137
今日推荐