单向链表的图示与代码实现

【数据结构】单向链表的相关操作

1、相关定义

线性表的链式存储
解决顺序存储的缺点,插入和删除,动态存储问题。

特点

​ 线性表链式存储结构的特点是一组任意的存储单位存储线性表的数据元素,存储单元可以是连续的,也可以不连续。可以被存储在任意内存未被占用的位置上。所以前面的顺序表只需要存储数据元素信息就可以了。在链式结构中还需要一个元素存储下一个元素的地址。为了表示每个数据元素,ai与其直接后继数据元素ai+1之间的逻辑关系,对ai来说,除了存储其本身的信息外,还需要存一个指示器直接后续的信息。把存储元素信息的域叫数据域,把存储直接后继位置的域叫指针域。这两部分信息组成数据元素ai的存储映像,叫结点(Node);

2、单向链表的相关操作和图解

1、单向链表的C语言描述

在这里插入图片描述

/*存储的数据类型*/
typedef int DataType;
/*结点类型*/
typedef struct node
{
	DataType Data;    //数据域
	struct node *pNext;   //指针域
}LinkNode;
/*标签类型*/
typedef struct list{
	LinkNode *pHead;  //头节点指针
	int cLen;         //节点个数
}LinkList;

2、链表的相关操作

  • 链表的创建

    原理如图所示:

在这里插入图片描述

LinkList *creatLinkList()
{
	LinkList *pList = malloc(sizeof(LinkList));
	if (NULL == pList)
	{
		perror("fail to malloc");
		return NULL;
	}
	pList->pHead = NULL;
	pList->cLen = 0;

	return pList;
}

int IsEmpty(LinkList *pList)//判空函数
{
    return pList->cLen == 0;
}
  • 链表的插入(头插与尾插)

    原理如图所示: 在这里插入图片描述

int insertHeadLinkList(LinkList *pList,DataType Data)//链表的头插
{
	LinkNode *pInsertNode = malloc(sizeof(LinkNode));
	if (NULL == pInsertNode)//判断是否malloc成功
	{
		perror("fail to malloc");
		return -1;
	}
	pInsertNode->Data = Data;
	pInsertNode->pNext = pList->pHead;
	pList->pHead = pInsertNode;
	pList->cLen++;
	return 0;
}
int insertTailLinkList(LinkList *pList,DataType Data) //链表的头插(待验证)
{
    LinkNode * pTmpNode = pList->pHead;
    LinkNode * pInsertNode = malloc(sizeof(LinkNode));
    if (NULL == pInsertNode)
	{
		perror("fail to malloc");
		return -1;
	}
    pInsertNode->pNext= NULL;
    while(pTmpNode->pNext !=NULL) //先用临时指针遍历到链表的末尾
    {
        pTmpNode = pTmpNode->pNext ;
    }
    pTmpNode->pNext = pInsertNode ;
    pList->cLen++;
    return 0;
}
  • 链表的删除 (头删与尾删)

在这里插入图片描述

int deleteTailLinkList(LinkList *pList)//链表的尾删
{
	if (isEmptyLinkList(pList))//先判定链表是否为空,如果为空,就退出删除链表操作
	{
		return 0;
	}
	else if (pList->cLen == 1)//如果只有一个节点,就采取头删操作
	{
		deleteHeadLinkList(pList);
	}
	else
	{
		LinkNode *pTmpNode = pList->pHead; //开辟一个临时指针指向头结点
		while (pTmpNode->pNext->pNext != NULL)//将临时指针指向倒数第二个指针
		{
			pTmpNode = pTmpNode->pNext;
		}
		free(pTmpNode->pNext);//free最后一个节点
		pTmpNode->pNext = NULL;
		pList->cLen--;
	}

	return 0;
}
int deleteHeadLinkList(LinkList *pList)//链表的头删
{
    if (isEmptyLinkList(pList))//先判定链表是否为空,如果为空,就退出删除链表操作
	{
		return 0;
	}
    LinkNode * pTmpNode =pList->Phead ;// 定义一个临时指针指向头结点
    pTmpNode->pNext = pList->Phead; //把标签的head指针指向第二个节点
    free(pTmpNode);//把第一个节点free掉
    return 0 ;
}
  • 链表的查找

在这里插入图片描述

LinkNode *findNodeLinkList(LinkList *pList,DataType data)
{
	LinkNode *pFindNode = pList->pHead;// 定义一个pFindNode指针指向头结点
	while (pFindNode != NULL)//用pFindNode向后遍历
	{
		if (pFindNode->Data == data)//如果发现待查找的节点
		{
			return pFindNode;//将该节点返回
		}
		pFindNode = pFindNode->pNext;
	}

	return NULL;
}

  • 链表的修改

    查到需要修改的节点,修改他的值

在这里插入图片描述


int modifyNodeLinkList(LinkList *pList,DataType oldData,DataType newData)
{
	LinkNode *pFindNode = NULL;

	if ((pFindNode = findNodeLinkList(pList,oldData)) != NULL)
	{
		pFindNode->Data = newData;
		return 0;
	}
	else
	{
		return -1;
	}

}
  • 链表的销毁

    先用尾删将节点free掉,再把Linklist free 掉,最后再把指向plist的指针置空;

    void destroyLinkList(LinkList **ppList)//链表的销毁
    {
    	while ((*ppList)->pHead != NULL)
    	{
    		deleteHeadLinkList(*ppList);
    	}
    	free(*ppList);
    	*ppList = NULL;//将指向链表指针也指空
    
    	return ;
    }
    

    欢迎大家讨论交流

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值