链表的基本算法。

今天我们来学习一波有关链表的基本算法。

#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#include<Windows.h>


// 值类型 
typedef int DataType; 

typedef struct SListNode { 
 DataType data; // 值 
struct SListNode *pNext; // 指向下一个结点 
} SListNode; 

// 初始化 
void SListInit(SListNode **ppFirst)
{
	SListNode *pNode=*ppFirst;
	assert(ppFirst!=NULL);              //初始化一个空链表。
	pNode=NULL;
}

void SListsetup(DataType data)
{
	SListNode *NewNode=(SListNode *)malloc(sizeof(SListNode));
	assert(NewNode);
	NewNode->data=data;
	NewNode->pNext=NULL;
}

// 尾部插入 
void SListPushBack(SListNode** ppFirst, DataType data)
{
	SListNode *pNode;
	SListNode *pNewNode=(SListNode *)malloc(sizeof(SListNode));   //开辟一个空间,将data赋给它,并将pNext赋成NULL。
	pNewNode->data=data;
	pNewNode->pNext=NULL;
	pNode=*ppFirst;                    //定义一个变量指向首元素。
	if(pNode==NULL)
	{
		pNode->data=data;              //可简写为  *pNode=pNewNode;
		pNode->pNext=NULL;
	}
	while(pNode->pNext!=NULL)
	{
		pNode=pNode->pNext;          //循环得到最后一位数。将它的pNext赋值成data。
	}
	pNode->pNext=pNewNode;
	free(pNewNode);                  //释放。
}
	


// 头部插入 
void SListPushFront(SListNode **ppFirst, DataType data)
{
	SListNode *pNewNode=(SListNode *)malloc(sizeof(SListNode));
	if(ppFirst==NULL)
	{                                     //如果为空,就直接赋值。
		pNewNode->data=data;
		pNewNode->pNext=NULL;
	}
	else{
	pNewNode->data=data;                 //否则将开辟出来的空间的pNext赋值为原来第一个元素的地址。
	pNewNode->pNext=*ppFirst;
	}
	free(pNewNode);
}



// 尾部删除 
void SListPopBack(SListNode **ppFirst)
{
	SListNode *pNode,*q;
	assert(ppFirst!=NULL);
	if((*ppFirst)->pNext==NULL)          //如果只有一个元素,那就直接删除。
	{
		free(*ppFirst);
		*ppFirst=NULL;
	}
	pNode=*ppFirst;
	while(pNode->pNext->pNext!=NULL)        //这一步是为了找到倒数第二个数。将它的pNext赋值成NULL。
	{
		pNode=pNode->pNext;
	}
	q=pNode->pNext;
	pNode->pNext=NULL;
	free(q);
}


// 头部删除 
void SListPopFront(SListNode **ppFirst)
{
	SListNode *pNode,*m;
	assert(ppFirst!=NULL);
	pNode=*ppFirst;
	m=pNode->pNext;
	free(pNode);
	*ppFirst=m;            
}

// 给定结点插入,插入到结点前 
void SListInsert(SListNode **ppFirst, SListNode *pPos, DataType data)
{
	SListNode *pNode=*ppFirst;
	SListNode *pNewNode=(SListNode *)malloc(sizeof(SListNode));
	assert(ppFirst!=NULL);
	pNewNode->pNext=pPos;
	pNewNode->data=data;         //要插入的空间的data赋值data,pNext赋值为pPos。
	if(*ppFirst==pPos)              //如果第一个是指定节点就直接调用头插函数。
	{
		SListPushFront(ppFirst,data);
		return;
	}
	while(pNode->pNext!=pPos)   //循环找到给定节点前的那个数。
	{
		pNode=pNode->pNext;
	}
	pNode->pNext=pNewNode;      //将它的pNext赋值成要插入的值。
	free(pNewNode);
}
	

// 给定结点删除 
void SListErase(SListNode **ppFirst, SListNode *pPos)
{
	SListNode *pNode=*ppFirst;
	if(*ppFirst==pPos)           //如果给定节点为第一个,就直接调用头删函数。
	{
		SListPopFront(ppFirst);
		return;
	}
	while(pNode->pNext!=pPos)               //循环找到给定节点的上一个数。
	{
		pNode=pNode->pNext;
	}
	pNode->pNext=pNode->pNext->pNext;   //pNode->pNext=pPos->pNext 
	free(pPos);
}
// 按值查找,返回第一个找到的结点指针,如果没找到,返回 NULL 
SListNode *SListFind(SListNode *pFirst, DataType data)
{
	SListNode *pNode;
	assert(pFirst!=NULL);
	for(pNode=pFirst;pNode!=NULL;pNode=pNode->pNext)         //循环寻找这个值第一次出现的位置。
	{
		if(pNode->data==data)
		{
			return pNode;               //找到返回它的节点指针,否则返回NULL。
		}
	}
	return NULL;
}

// 按值删除,只删遇到的第一个 
void SListRemove(SListNode **ppFirst, DataType data)
{
	SListNode *pNode;
	assert(ppFirst!=NULL);
	pNode=SListFind(*ppFirst, data);        //调用查找函数。
	if(pNode==NULL)
	{
		printf("This data is not exit!\n");     //如果为NULL,则表示没这个值。
	} 
	else{
		SListErase(ppFirst,pNode);          //否则调用根据节点删除函数。
	
	}

}
// 按值删除,删除所有的 
void SListRemoveAll(SListNode **ppFirst, DataType data)
{
	SListNode *pNode,*x;
	assert(ppFirst!=NULL);
	x=SListFind(*ppFirst, data);
	if(x==NULL)
	{
		printf("This data is not exit!\n");
	}
	else{
		for(pNode=*ppFirst;pNode!=NULL;pNode=pNode->pNext)   //从头开始寻找与值一样的节点所在位置,然后分别删除它们。
		{
			if(pNode->data==data)
			{
				SListErase(ppFirst,pNode);
			}
		}
	}
}

int SListSize(SListNode **ppFirst)//统计链表中一共有多少个数
{
	int size=0;
	SListNode *pNode=*ppFirst;
	for(;pNode!=NULL;pNode=pNode->pNext)    //循环计算链表中有几个数。
	{
		size++;
	}
	printf("The nnumber is %d\n",size);   //输出结果。
	return 0;
}


// 销毁 
void SListDestroy(SListNode **ppFirst)
{
	SListNode *r;
	SListNode *pNode=*ppFirst;
	for(;pNode!=NULL;pNode=r)
	{
		r=pNode->pNext;
		free(pNode);
	}
	*ppFirst=NULL;
}

以上就是我所编写的算法,其中可能有很多错误,希望大家给些意见。

    原文作者:飞电侠10
    原文地址: https://blog.csdn.net/ymk1507050118/article/details/80683081
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞