无头单链表的操作

△节点结构
typedef定义
{
1.结点元素
2.Next的指针
}

//不带头节点的单链表 
typedef int SDataType;

// 节点结构 
typedef struct SListNode
{
	SDataType _data;
	struct SListNode* _pNext;
}Node,*pNode;

△链表结构
typedef定义
{
头指针
}

// 给一个链表结构 
typedef struct SList
{
	Node* _pHead;
}SList;

△链表的初始化
1.断言
2.头指针指向NULL

// 链表的初始化 
void SListInit(SList* pl)
{
	assert(pl);
	pl->_pHead = NULL;

}

△创建新结点
1.为新结点申请动态内存空间
2.判断新结点是否为空
3.将元素的值赋给新结点
4.将新结点的Next域指向NULL

//创建一个结点
pNode BuyListNode(SDataType data)
{
	pNode pNewNode = (Node*)malloc(sizeof(Node));
	if (pNewNode == NULL)
	{
		assert(0);
		return NULL;
	}
	pNewNode->_data = data;
	pNewNode->_pNext = NULL;
}

△尾插法
0.断言assert( )
1.链表为空
让头指针指向新结点
2.只有一个结点
让头指针的Next指向新结点
3.有多个结点
遍历,找到链表中Next域为空的结点,将该结点的Next指向新结点

void SListPushBack(SList* pl, SDataType data)
{
	//1.链表为空
	if (pl->_pHead == NULL)
	{
		pl->_pHead = BuyListNode(data);
	}
	//2.只有一个结点
	else if (pl->_pHead->_pNext == NULL)
	{
		pl->_pHead->_pNext = BuyListNode(data);
	}
	//3.有多个结点
	else
	{
		pNode cur = pl->_pHead;
		while (cur->_pNext!=NULL)
		{
			cur = cur->_pNext;
		}
		cur->_pNext = BuyListNode(data);
	}
}

△尾删法
1.断言assert
2.链表为空
返回;
3.只有一个结点
free掉头指针的Next域;
让头指针指向NULL;
4.有多个结点
设置指针cur,保存链表的最后一个结点;
设置指针pre,保存链表的倒数第二个结点;
让cur指向头指针,将指针pre置为空,然后让cur从链表第一个元素向后遍历,pre指向cur,当cur指向的结点的Next域为NULL时,遍历结束,此时,cur指向链表的最后一个结点,pre指向了链表的倒数第二个结点,free掉cur,将pre的Next域指向空。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

// 尾删法
void SListPopBack(SList* pl)
{
	assert(pl);
	if (NULL == pl->_pHead)
	{
		printf("链表为空!");
		return NULL;
	}
	//只有一个结点
	else if (pl->_pHead->_pNext==NULL)
	{
		free(pl->_pHead->_pNext);
		pl->_pHead = NULL;
	}
	//有多个结点
	else
	{
		pNode cur = pl->_pHead;
		pNode pre = NULL;
		while (cur->_pNext)
		{
			pre = cur;
			cur = cur->_pNext;
		}
		free(cur);
		cur = NULL;
		pre->_pNext = NULL;
	}
}

△头插法
1.判表空
2.设置一个cur指针存放新结点
3.将cur指向头指针的Next域,将头指针指向cur

void SListPushFront(SList* pl, SDataType data)
{
	assert(pl);
	if (pl->_pHead == NULL)
	{
		pl->_pHead= BuyListNode(data);
	}
	else 
	{
		pNode cur = BuyListNode(data);
		cur->_pNext = pl->_pHead;
		pl->_pHead = cur;

	}
}

△头删法
1.判表空
2.只有一个结点:
将头指针指向NULL
3.有多个结点:
设置一个指针cur指向头指针的Next域,将头指针指向cur的Next域,free掉cur

void SListPopFront(SList* pl)
{
	assert(pl);
	if (pl->_pHead == NULL)
	{
		printf("链表为空!");
		return NULL;
	}
	else if (pl->_pHead->_pNext==NULL)
	{
		pl->_pHead = NULL;
	}
	else
	{
		pNode cur = pl->_pHead;
			pl->_pHead = cur->_pNext;
			free(cur);
	}
}

△在链表pos位置后插入置为data的节点
1.判断插入位置是否合法
2.设置两个指针cur,pre,cru指针指向头指针,pre指针指向NULL,若cur不等于pos,cur继续往后走,若cur等于pos,将data存放在pre中,将Pre指向cur的Next域,将cur的Next域指向pre。

猜你喜欢

转载自blog.csdn.net/qq_41181857/article/details/86575087