单链表基本操作

目录

0.结点以及单链表的空间开辟

1.打印链表

2.尾插法

 3.头插法

 4.尾删法

5.头删法

 6.单链表的查找

7.单链表的插入

8补充.在一个无头单链表中的某一个结点的前面插入一个值x,如何插入(不知道头指针)

 9.单链表的删除

9.1删后一个位置:存在两种情况

9.2 删除当前位置


0.结点以及单链表的空间开辟

typedef struct SListNode
{
	SLTDataType data;
	struct SListNode* next;

}SLTNode;
LTNode* BuySLNode(SLTDataType x)
{
	SLTNode* node = (SLTNode*)malloc(sizeof(SLTNode);
	node->data = x;
	node->next = NULL;

	return node;
}

 

1.打印链表

void SListPrint(SLTNode* plist)
{
	SLTNode* cur = plist;
	while (cur != NULL)
	{
		printf("%d ", cur->data);
		cur = cur->next;//赋值下一个结点的地址,即指向下一个结点
	}
	printf("\n");
}

2.尾插法

LTNode* BuySLNode(SLTDataType x)
{
	SLTNode* node = (SLTNode*)malloc(sizeof(SLTNode);
	node->data = x;
	node->next = NULL;

	return node;
}


void SListPushBack(SLTNode* plist, SLTDataType x)
{
	//先遍历找尾
	SLTNode* tail = plist;
	while (tail->next != NULL)
	{
		tail = tail->next;
	}
	SListNode* newnode = BuySLTNode(x);
	
	tail->next = newnode;
}

上述尾插法存在问题:空表时出现问题

 

 

 改正如下,还是出现空

void SListPushBack(SLTNode* plist, SLTDataType x)
{
	SLTNode* newnode = BuySLTNode(x);
	//1空
	//2非空
	if (plist == NULL)
	{
		plist = newnode;
	}
	else
	{
		//遍历找尾
		SLTNode* tail = plist;
		while (tail->next != NULL)
		{
			tail = tail->next;
		}
		tail->next = newnode;
	}
}

 TestSList1()函数和SListPushBack()函数建立不同的栈帧。其中结点x出现在堆上

 

 改正如下:加入二级指针,TestSList1()函数中加入&

void SListPushBack(SLTNode**pplist, SLTDataType);
void SListPushBack(SLTNode** pplist, SLTDataType x)
{
	SLTNode* newnode = BuySLTNode(x);
	//1空
	//2非空
	if (*pplist == NULL)
	{
		*pplist = newnode;
	}
	else
	{
		//遍历找尾
		SLTNode* tail = *pplist;
		while (tail->next != NULL)
		{
			tail = tail->next;
		}
		tail->next = newnode;
	}
}

 

 3.头插法

void SListPushFront(SLTNode** pplist, SLTDataType x)
{
	SLTNode* newnode = BuySLTNode(x);
	newnode->next = *pplist;
	*pplist = newnode;
}

链表为空的时候情况如下,即头插法不考虑链表为空的情况

 4.尾删法

若代码如下,出现问题

void  SListPopBack(SLTNode* plist)
{
	SLTNode* tail = plist;
	while (tail->next != NULL)
	{
		tail = tail->next;
	}
	free(tail);
	tail = NULL;
}

 删除最后一个结点后还应把前一个结点的next域置空

void  SListPopBack(SLTNode* plist)
{
	SLTNode* prev = NULL;
	SLTNode* tail = plist;
	while (tail->next != NULL)
	{
		prev = tail;
		tail = tail->next;
	}
	free(tail);
	tail = NULL;

	prev->next = NULL;
}

 若出现下面两种情况时仍有问题:前者tail为空指针,不进入while循环,后者tail不等于空但是tail的next域为空,且prev为空

void  SListPopBack(SLTNode**pplist)
{
	//1.没有结点
	//2.一个结点
	//3.多个结点
	if (*pplist = NULL)
	{
		return;
	}
	else if((*pplist)->next == NULL)
	{
		free(*pplist);
		*pplist = NULL;
	}
	else
	{
		SLTNode* prev = NULL;
		SLTNode* tail = *pplist;
		while (tail->next != NULL)
		{
			prev = tail;
			tail = tail->next;
		}
		free(tail);
		tail = NULL;

		prev->next = NULL;
	}
}

5.头删法

void SListPopFront(SLTNode**pplist)
{
	if(*pplist = NULL)
	{
		return;
	}
	else
	{
		SLTNode* next = (*pplist)->next;
		free(*pplist);
		*pplist = next;
	}
}

若只有一个结点

 

 6.单链表的查找


SLTNode* SListFind(SLTNode* plist, SLTDataType x)
{
	SLTNode* cur = plist;
	//while(cur!=NULL)
	while (cur)
	{
		if (cur->data == x)
		{
			return cur;
		}
		cur = cur->next;
	}
	return NULL;
}

7.单链表的插入

单链表在Pos位置之后插入x

void SListInsertAfter(SLTNode* pos, SLTDataType x)
{
	assert(pos);
	SLTNode* newnode = BuySLTNode(x);
	pos->next = newnode;
	newnode->next = pos->next;
}

 

 上述代码导致d3地址丢失,改正如下

void SListInsertAfter(SLTNode* pos, SLTDataType x)
{
	assert(pos);
	SLTNode* newnode = BuySLTNode(x);
	newnode->next = pos->next;
	pos->next = newnode;
}

 

 单链表在pos位置之前插入x(难点在于找pos的前一个结点,需要从头开始找)

 

void SListInsert(SLTNode*plist, SLTNode* pos, SLTDataType x)
{
	assert(pos);
	SLTNode* newnode = BuySLTNode(x);
	SLTNode* prev = NULL;
	SLTNode* cur = plist;
	while (cur != pos)
	{
		prev = cur;
		cur = cur->next;
	}
	prev->next = newnode;
	newnode->next = pos;
}
	

 若pos为第一个的时候

改正如下  

void SListInsert(SLTNode**pplist, SLTNode* pos, SLTDataType x)
{
	assert(pos);
	SLTNode* newnode = BuySLTNode(x);

	if (pos == *pplist)//头插
	{
		newnode->next = pos;
		*pplist = newnode; 

	}
	else
	{
		SLTNode* prev = NULL;
		SLTNode* cur = *pplist;
		while (cur != pos)
		{
			prev = cur;
			cur = cur->next;
		}
		prev->next = newnode;
		newnode->next = pos;
	}
}

8补充.在一个无头单链表中的某一个结点的前面插入一个值x,如何插入(不知道头指针)

后插一个值为x的结点,然后跟后面的节点值(data值)交换

 9.单链表的删除

9.1删后一个位置:存在两种情况

 

 

 

void SListEraseAfter(SLTNode* pos)
{
	assert(pos);
	if (pos->next == NULL)
	{
		return;
	}
	else
	{
		SLTNode* next = pos->next;
		pos->next = next->next;
		free(next);
	}
}

 

9.2 删除当前位置

面临的问题:找pos位置的前一个->相当于头删->传二级指针

void SListEraseCur(SLTNode*plist,SLTNode*pos);

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值