Liste chaînée (haut) ---- liste chaînée individuellement (notes du coureur)

Lors de l'insertion de données au milieu de l'en-tête et de l'expansion de la table de séquence dynamique, il y aura toujours un gaspillage de ressources ou de performances, nous pouvons donc utiliser une liste chaînée à la place.

(Les tableaux séquentiels ont naturellement leurs propres avantages, et ils ont toujours leurs propres avantages sous différents aspects)

Avantages de la liste liée

  1. En termes d'espace, donnez de l'espace en fonction de la demande (ne causera pas de perte d'espace
  2. Pas besoin de déplacer des données lors de l'insertion au milieu d'en-têtes continus qui ne nécessitent pas d'espace physique.

liste liée

Une liste chaînée est une structure de stockage physique créée par un problème structurel qui n'est pas consécutif, et la connexion entre les listes chaînées de structure de stockage non séquentielle est réalisée par une connexion séquentielle de pointeurs.

Slistnode.h

#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
typedef int SLTdatetype; //为了方便未来更改存储数据
struct SListNode
{
    
    
	SLTdatetype date;
	struct SListNode* next;
};//单向链表的类型
typedef struct SListNode SListNode;//方便使用 单向链表类型
// 单链表打印
void SListPrint(SListNode* plist);
// 单链表尾插
void SListPushBack(SListNode** pplist, SLTdatetype x);
// 单链表的头插
void SListPushFront(SListNode** pplist, SLTdatetype x);
// 单链表的尾删
void SListPopBack(SListNode** pplist);
// 单链表头删
void SListPopFront(SListNode** pplist);
// 单链表查找
SListNode* SListFind(SListNode* plist, SLTdatetype x);
// 单链表在pos位置之前插入x
void SListInsert(SListNode** pplist, SListNode* pos, SLTdatetype x);
// 单链表删除pos位置的值
void SListErase(SListNode** pplist, SListNode* pos);

Slistnode.c

#include"work.h"

//对链表进行打印
void SListPrint(SListNode* plist)
{
    
    
	SListNode* cur = plist;
	while (cur != NULL)
	{
    
    
		printf("%d->", cur->date);
		cur = cur->next;
	}
	printf("NULL\n");
}

SListNode* BuyNode()//开辟一块新空间
{
    
    
	SListNode* newnode = malloc(sizeof(SListNode));//新的要插入的区域块
	if (newnode == NULL)//防止malloc开辟空间失败
	{
    
    
		perror("BuyNode");
		return NULL;
	}
	return newnode;
}

//尾部插入代码实现
void SListPushBack(SListNode** pplist, SLTdatetype x)
{
    
    
	SListNode* newnode = BuyNode();//得到新空间
	//初始化数据
	newnode->date = x;
	newnode->next = NULL;
	//尾插开始
	if (*pplist == NULL)//如果*pplist为空指针后面的tail也将为空指针而->是有解引用的作用的我们对空指针的解引用是违法行为
	{
    
    
		*pplist = newnode;
	}
	else
	{
    
    
		SListNode* tail = *pplist;
		while (tail->next != NULL)//让tail指向未增容时的链表尾部
		{
    
    
			tail = tail->next;
		}
		tail->next = newnode;
	}
}
//头部插入代码实现
void SListPushFront(SListNode** pplist, SLTdatetype x)
{
    
    
	SListNode* newnode = BuyNode();//得空间
	newnode->date = x;
	newnode->next = *pplist;
	*pplist = newnode;
}

//链表尾删实现
void SListPopBack(SListNode** pplist)
{
    
    
	assert(*pplist);
	if ((*pplist)->next == NULL)
	{
    
    
		free(*pplist);
		*pplist = NULL;
	}
	else
	{
    
    
		SListNode* tail = *pplist;
		SListNode* prev = *pplist;
		while (tail->next != NULL)//让tail指向未增容时的链表尾部
		{
    
    
			prev = tail;
			tail = tail->next;
		}
		prev->next = NULL;
		free(tail);
	}
}


void SListPopFront(SListNode** pplist)
{
    
    
	assert(*pplist);
	SListNode* next = (*pplist)->next;
	free(*pplist);
	*pplist = next;
}

//链表查找实现
SListNode* SListFind(SListNode* plist, SLTdatetype x)//辅助性的功能函数
{
    
    
	while (plist != NULL)
	{
    
    
		if (plist->date == x)
		{
    
    
			return plist;
		}
		plist = plist->next;
	}
	return NULL;
}

//定点插入实现pos前插入
void SListInsert(SListNode** pplist, SListNode* pos, SLTdatetype x)
{
    
    
	
	if (pos == *pplist)//如果要定点插入的在头部就和头插一样直接使用头插就好
	{
    
    
		SListPushFront(pplist, x);
	}//使用下面else的方式找pos前一位是无法定位到开头的所以需要这个分支
	else
	{
    
    
		SListNode* newnode = BuyNode();//创建新空间
		newnode->date = x;
		SListNode* prve = *pplist;
		//寻找pos的前一位
		while (prve->next != pos)
		{
    
    
			prve = prve->next;
		}
		//数据处理
		prve->next = newnode;
		newnode->next = pos;
	}
}
void SListErase(SListNode** pplist, SListNode* pos)
{
    
    
	if (pos ==*pplist)
	{
    
    
		SListPopFront(pplist);
	}//使用下面else的方式找pos前一位是无法定位到开头的所以需要这个分支
	else
	{
    
    
		SListNode* prve = *pplist;
		//寻找pos的前一位
		while (prve->next != pos)
		{
    
    
			prve = prve->next;
		}
		prve->next = pos->next;
		free(pos);
	}
}

main.c

#include"work.h"
void TestSList()
{
    
    
	SListNode* plist = NULL;//用于保存链表头部的地址
	SListPushBack(&plist, 1);
	SListPushBack(&plist, 2);
	SListPushFront(&plist, 0);
	SListPopBack(&plist);
	SListPopBack(&plist);
	SListPopBack(&plist);
	SListPrint(plist);

}
void TestSList2()
{
    
    
	SListNode* plist = NULL;//用于保存链表头部的地址
	SListPushBack(&plist, 1);
	SListPushBack(&plist, 2);
	SListPushBack(&plist, 3);
	SListPushBack(&plist, 4);
	SListNode* pos = SListFind(plist, 1);
	if (pos != NULL)
	{
    
    
		SListInsert(&plist, pos, 50);
	}
	SListPrint(plist);
}
void TestSList3()
{
    
    
	SListNode* plist = NULL;//用于保存链表头部的地址
	SListPushBack(&plist, 1);
	SListPushBack(&plist, 2);
	SListPushBack(&plist, 3);
	SListPushBack(&plist, 4);
	SListNode* pos = SListFind(plist, 1);
	if (pos != NULL)
	{
    
    
		SListErase(&plist, pos);
	}
	SListPrint(plist);
}
int main()
{
    
    
	TestSList3();
	return 0;
}

finir

À l'avenir, il y aura la mise en œuvre de la liste à double lien et la pratique des exercices. Si cela vous est utile, veuillez donner à Shu Wen un like et un favori. Merci.

Je suppose que tu aimes

Origine blog.csdn.net/qq_61434711/article/details/123155257
conseillé
Classement