【数据结构】2.1单链表

 

目录

一、单链表

1.链表的介绍

2.单链表的学习思维导图

3.顺序表和单链表的优缺点(重要)

4.单链表的头指针与头结点的区别(重要)

5.链表的实现(双指针法 & 返回值法)

·头插法(双指针 & 返回值)

·尾插法(双指针 & 返回值)

·头删法(双指针 & 返回值)

·尾删法(双指针 & 返回值)

5.1 单链表结点的存储结构

5.2 单链表的初始化

5.3 单链表的销毁

5.4 创建结点

5.5 打印单链表

 5.6 查找

 5.7 插入

 5.8 删除


 

一、单链表

1.链表的介绍

介绍一下链表的种类 今天学习的是单向  无头  非循环 链表

实际中链表的结构非常多样,以下情况组合起来就有8种链表结构:
1. 单向、双向
2. 带头、不带头
3. 循环、非循环
 
 

其中最常用的是

 

2.单链表的学习思维导图

 

 

3.顺序表和单链表的优缺点(重要)

 

 

4.单链表的头指针与头结点的区别(重要)

 

 

5.链表的实现(双指针法 & 返回值法)

以下是双指针法实现 这里把头插、尾插、头删、尾删放在前面

·头插法(双指针 & 返回值)

 

SListNode* SListPushFront(SListNode** pplist, SLTDataType x)//头插
{
    /*  1.空
	2.非空   */

	SListNode* newnode = BuySListNode(x);
	if (*pplist != NULL)
	{
		newnode->_next = *pplist;
		*pplist = newnode;
	}
	else
	{
		*pplist = newnode;
	}

}
SListNode* SListPushFront(SListNode* head, SLTDataType x)
{
	
	SListNode* newnode = (SListNode*)malloc(sizeof(SListNode));
	newnode->_data = x;
	newnode->_next = NULL;
	if (head == NULL)
	{
		head = newnode; //确定新的头
		return head;
	}
	else
	{
		 newnode->_next = head ;
		
	}
        head = newnode;
	return head;
}

·尾插法(双指针 & 返回值)

 

void SListPushBack(SListNode** pplist, SLTDataType x)//尾插法(双指针)
//plist 是pplist的地址 *pplist就是plist
{
	SListNode* newnode = BuySListNode(x);

	if (*pplist == NULL)
	{
		*pplist = newnode;
	}
	else
	{
		SListNode* tail = *pplist;//找尾
		while (tail->_next != NULL)
		{
			tail = tail->_next;
		}
		tail->_next = newnode;

	}


}
void SListPushBack(SListNode* head, SLTDataType x)//用返回值的方式进行尾插
{
	SListNode* newnode = (SListNode*)malloc(sizeof(SListNode));
	newnode->_data = x;
	newnode->_next = NULL;
	if (head == NULL)   //先判断 如果没有结点的情况  考虑一下边界的情况
	{
		head = newnode;
		return head;
	}
	else
	{

		SListNode* tail = head;
		while (tail->_next != NULL)
		{
			tail = tail->_next;
		}

		tail->_next = newnode;
		return head;
	}

}

 

·头删法(双指针 & 返回值)

SListNode* SListPopFront(SListNode** pplist)                //头删 双指针法
{/*
	1.空
	2.一个
	3.两个以上*/
	//SListNode* first = *pplist;
	if (*pplist == NULL)
	{
		return ;
	}
	else if ((*pplist)->_next == NULL)
	{
		free(*pplist);
		//plist = NULL;//达不到效果 因为plist只是局部变量
		*pplist = NULL;

	}
	else
	{
		SListNode* _next = (*pplist)->_next;
		free(*pplist);
		*pplist = _next;
	}

}
SListNode* SListPopFront(SListNode* head) //头删 返回值法
{
	SListNode* cur = head;
	if (cur == NULL)
	{
		return ;
	}
	else if (cur->_next == NULL)
	{
		free(cur);
		cur = NULL;
	}
	else
	{
		SListNode* next = cur->_next;
		free(cur);
		cur = next;
	}
	head = cur;
	return head;
}

 

·尾删法(双指针 & 返回值)

SListNode* SListPopBack(SListNode** pplist)  //尾删 双指针法
{
	assert(pplist);
	//第一步 找尾
	SListNode* prev = NULL;   //定义tail上一个数 
	SListNode* tail = *pplist;
	//1.空 、只有一个结点
	//2.两个及以上的结点
	if (tail == NULL || tail->_next == NULL)
	{
		free(tail);
		*pplist = NULL;
	}

	else
	{
		while (tail->_next)
		{
			prev = tail;
			tail = tail->_next;
		}
		free(tail);
		tail = NULL;
		prev->_next = NULL;

	}
	
}
SListNode* SListPopBack(SListNode* head)  //尾删 返回值法
{
	assert(head);
	//第一步 找尾
	SListNode* prev = NULL;   //定义tail上一个数 
	SListNode* tail = head;
	//1.空 、只有一个结点
	//2.两个及以上的结点
	if (tail == NULL || tail->_next == NULL)
	{
		free(tail);
		head = NULL;
	}
	else
	{
		while (tail->_next)
		{
			prev = tail;
			tail = tail->_next;
		}
		free(tail);
		tail = NULL;
		prev->_next = NULL;

	}	
	return head;

}



5.1 单链表结点的存储结构

typedef int SLTDateType;
typedef struct SListNode
{
 SLTDateType _data;       //数据域
 struct SListNode* _next; //指针域
}SListNode;

5.2 单链表的初始化

void SListInit(SListNode* plist)
{
        assert(plist);
	plist = (SListNode*)malloc(sizeof(SListNode));
	plist->next = NULL;
}

5.3 单链表的销毁

void SListDestory(SListNode** pplist)//销毁
{
    SListNode* plist = NULL;

    while (*pplist)
    {
        tmp = (*pplist)->_next;
        free(*pplist);
        (*pplist) = plist; 
    }

}

5.4 创建结点

SListNode* BuySListNode(SLTDataType x)  //把结点开好,并进行初始化
{
	//动态申请一个空间,用来存放一个结点,并用临时指针node指向这个结点
	SListNode* node = (SListNode*)malloc(sizeof(SListNode));

	node->_data = x;   //将数据域存储到当前结点的data域中
	node->_next = NULL;//设置当前结点的后继指针为空
	return node;
}

5.5 打印单链表

void  SListPrint(SListNode* plist)//打印
{
	SListNode* cur = plist;
	while (cur != NULL)//依次遍历一遍
	{
		printf("%d->", cur->_data);
		cur = cur->_next;
	}
	printf("NULL\n");
}

 5.6 查找

SListNode* SListFind(SListNode* plist, SLTDataType x) //查找
{
	SListNode* cur = plist;
	while (cur)
	{
		if (cur->_data == x)
		{
			return cur;
			
		}
		cur = cur->_next;

	}
	return NULL;
}

 5.7 插入

void SListInsertAfter(SListNode* pos, SLTDataType x)  //插入后一个  中间 边界  头部 都可以使用
{
	assert(pos);
	SListNode* next = pos->_next;
	//pos newnode next
	SListNode* newnode = BuySListNode(x);
        newnode->_next = next;
	pos->_next = newnode;
	

}

 5.8 删除

void SListEraseAfter(SListNode* pos)//删除后一个 中间 边界  头部 都可以使用
{
	//pos newnode next
	assert(pos);
	SListNode* next = pos->_next;
	if (next != NULL)
	{
		SListNode* nextnext = next->_next;
		free(next);
		pos->_next = nextnext;

	}
	
}

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

  • 4
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值