【2022/3/25】单链表和部分功能实现

链表

一、什么是链表

链表是数据结构中线性表的一种,其中每个元素实际上是一个单独的结构体对象,二所有对象都通过每个元素中的指针链接在一起。它是以结构体为节点,将一个结构体看成数据域和指针两个部分,数据域用于存储数据,指针域用于链接下一个节点。

二、链表的特点

1、没有固定产大姑,可以自由增加节点

2、链表能够实现快速插入删除数据

3、与数组相似,链表也是一种现象数据结构

4、链表的未借点的后续必定指向空。

链表和数据的区别:数组是顺序存储的,而链表是链式存储的。

image-20220319144650047

单链表

单链表结构体的声明

typedef int Type;//数据类型通过typedef取别名的形式来进行灵活使用
struct Node{//单链表节点结构体声明
    Type data;//链表节点的数据域,用于存储数据
    structNode *next;//链表节点的指针域,用于指向下一个节点
};
struct LinkList{//单链表结构体的声明
    struct Node *head;//链表头结点的指针域,用于指向链表都开头
    struct Node *next;//链表尾节点的指针域,用于指向链表都末尾
    int lenth;//链表的长度
};

链表的功能实现

1.单链表的创建

LL* list_init() 
{
LL* temp = (LL*)malloc(sizeof(LL));
if (NULL == temp)
{//如果动态开辟内存失败,temp指针指向了NULL
	printf("单链表创建失败!");
	return NULL;
}
temp->head = NULL;//单链表头节点指针置空
temp->end = NULL;//单链表尾指针置空
temp->lenth = 0;
return temp;
}

2.单链表的节点的连接

3.单链表的输出

void list_print(LL* list)  
{
	if (NULL == list)
	{//如果整个链表不存在
		printf("单链表不存在,数据输出失败!\n");
		return;
	}
	if (NULL == list->head)
	{//如果链表为空
		printf("单链表没有数据,数据输出失败!\n");
		return;
	}
	for (Node* temp = list->head; temp != NULL; temp = temp->next)
	{
		printf("%d", temp->data);
	}
	puts("NULL\n");
}

4.单链表的节点的插入

void list_insert_end(LL* list, Type val)//尾插法
{
	if (NULL == list)
	{//如果整个链表不存在,数据插入失败
		printf("单链表创建失败!\n");
		return;
	}
	
	if (NULL == list->head)//单链表为空创建第一个节点
	{
		/*Node* New = (Node*)malloc(sizeof(Node));
		New->data = val; 
		list->head = New;
		list->end = New;
		New->next = NULL;*/
		list->head = list->end = node_init(val);
		
		list->lenth++;
	}
	else//如果创建的不是第一个节点,需要将新节点连接上链表上一个节点并将尾指针改变指向 
	{
		/*Node* New = (Node*)malloc(sizeof(Node));
		New->data = val; 
		list->end->next = New;//新节点接上链表尾部(前后节点之间建立连接)
		list->end = New;//新节点成为新的尾部
		New->next = NULL;*/
		//创建一个 新节点连接上链表尾部
		list->end = list->end->next= node_init(val);//新节点成为新的尾部(从右往左算)
		list->lenth++;
	}
}

5.单链表节点的删除

Type list_delete_Node(LL* list, int index)
{
	if (NULL == list)
	{//如果整个链表不存在,数据删除失败
		printf("单链表删除失败!\n");
		return;
	}
	if (NULL == list->head)
	{//如果链表为空
		printf("单链表没有数据,数据删除失败!\n");
		return;
	}
	if (index <= 0 || index >= list->lenth + 1)
	{
		printf("数据输入位置错误!\n");
		return;
	}
	if (1 == index)
	{//删除头部节点
		Node* temp = list->head;
		list->head = list->head->next;//记录被删除节点的位置
		Type val = temp->data;//记录被删除节点的数据
		free(temp);
		list->lenth--;
		return val;
	}
	if (index == list->lenth)
	{//删除尾部节点
		Node* temp = list->end;
		for (int i = 1; i < index - 1; i++)
		{//找到删除位置的前一个节点
			temp = temp->next;
		}
		Type val = list->end->data;//记录尾部节点数据
		free(list->end);
		list->end = temp;
		return val;
	}
	
	//删除中间节点
	
	//找到删除位置
	Node* temp1 = list->head;
	for (int i = 1; i < index - 1; i++)
	{//找到删除位置的前一个节点
		temp1 = temp1->next;
	}
	Node* temp2 = temp1->next;//指向被删除的节点
	Type val = temp2->data;//指向被删除节点的数据

	temp1->next = temp2->next;//删除位置的前一个节点的指针域跳过被删除位置的节点,指向下一个节点
	free(temp2);//释放掉被删除节点的内存
}

6.向单边表指定位置插入数据

void list_insert(LL* list, int index, Type val)
{
	if (NULL == list)
	{//如果整个链表不存在,数据插入失败
		printf("单链表创建失败!\n");
		return;
	}
	if (index <= 0 || index >= list->lenth + 1)
	{
		printf("数据输入位置错误!\n");
		return ;
	}

	Node* temp = list->head;
	for (int i = 1; i < index-1; i++)
	{//找到插入位置的前一个节点
		temp = temp->next;
	}
	//有两种特殊情况,在头部和尾部插入

	//在头节点之前插入
	if (1 == index)
	{//如果插入位置是第一个
		Node* New = node_init(val);//创建新节点
		New->next = list->head;
		list->head = New;//新节点成为新的头节点
		list->lenth++;
		return;
	}
	//在尾节点之后插入
	if (list->lenth + 1 == index)
	{//如果插入位置刚好比链表长度大一个(在链表尾部之后插入新数据)
		list->end = list->end->next = node_init(val);
		list->lenth++;
		return;
	}

	//中间节点的插入
	Node* New = node_init(val);//创建新节点
	New->next = temp->next;//新节点连接插入位置之后的节点
	temp->next = New;//链表插入位置之前的节点连接上新节点
	
	list->lenth++;
}

7.获取单链表指定位置上的数据

8.单链表的销毁

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值