单链表的建立、头插、尾插、给定位置插入、尾删、给定位置删除、节点的查找、链表的销毁:
#include<stdio.h>
#include<string.h>
#include<assert.h>
#include<stdlib.h>
typedef int DataType;
//pHead:头结点 ppHead:指向pHead的指针 *ppHead:存放的是pHead指向的地址
typedef struct SListNode
{
struct SListNode* _next;
DataType _data;
}SListNode;
SListNode* BuySListNode(DataType x)
{
SListNode* node=(SListNode*)malloc(sizeof(SListNode)*1);//创建一个结构体指针指向开辟的结构体空间
node->_next=NULL;//通过指针访问内部成员,将_next指针指向地址置空
node->_data=x;//同理
return node;//返回指针
}
void SListPrint(SListNode* pHead)//链表的打印
{
//assert(pHead);//判断头结点指针内部地址是否为空,是就进
SListNode* node=pHead;
while(node!=NULL)
{
printf("%d\n",node->_data);
node=node->_next;//通过指针访问内部成员,(判断第一个节点的下一个地址是否为空,是否存在下一节点)将pHead指向下一个节点
}
}
void SListDestory(SListNode** ppHead)//链表的销毁
{
assert(*ppHead);//判断链表是否为空
SListNode* node=*ppHead;//node指向第一个节点
SListNode* noode=NULL;//建立noode指针
while(node)//进行循环遍历节点,并销毁
{
noode=node->_next;;//令noode指向当前节点的下一个节点
free(node);//销毁当前节点空间
node=noode;//将下一节点的地址给node并进入循环判断条件
}
*ppHead=NULL;//销毁完成,将头指针置空
}
void SListPushBack(SListNode** ppHead, DataType x)//尾部压入(建立二级指针,指向pHead)
{
SListNode* newnode=*ppHead;//建立指针指向第一个节点
if(*ppHead==NULL)//判断是否为空链表,1.空链表
{
SListNode* Node= BuySListNode(x);//建立一个新节点,并使node指向它
*ppHead=Node;//使得头指针指向新建立的节点
(*ppHead)->_next=NULL;//节点的_next置空
}
else//2.非空链表
{
while(newnode->_next!=NULL)//循环找尾
{
newnode=newnode->_next;//当循环进入最后一次时,newnode表示的是最后一个节点
}
SListNode* Node= BuySListNode(x);//建立新的节点
Node->_next=NULL;//新节点的next指针置空
newnode->_next=Node;//将Node指向的节点的地址给当前节点的_next
}
}
void SListPopBack(SListNode** ppHead)//尾删
{
assert(*ppHead);//判断第一个节点是否存在
SListNode *parent=NULL;
SListNode *newnode=*ppHead;
if(newnode->_next==NULL)//1.如果只有一个节点
{
free(newnode);//删除节点
//newnode=NULL;
*ppHead=NULL;//头指针置空
}
else//2.若果存在多个节点
{
while(newnode->_next!=NULL)//判断节点地址是否为空,空表示没有节点,非空表示存在节点
{
parent=newnode;//parent指向前一个节点
newnode=newnode->_next;//newnode指向当前节点
}
free(newnode);//销毁尾节点
parent->_next=NULL;//前一节点的next指针置空
}
}
void SListPushFront(SListNode** ppHead, DataType x)//头插
{
if(*ppHead==NULL)//1.空链表
{
SListNode* node= BuySListNode(x);//通过指针保存新节点的地址
*ppHead=node;//头指针由指空变为指向新节点的地址
(*ppHead)->_next=NULL;//将新节点的指向下一个节点的next指针指空
}
else//2.非空链表
{
SListNode* newnode= BuySListNode(x);//买一个新节点,并将它的新地址给newnode指针
SListNode* next=*ppHead;//将第一个节点的地址给next
*ppHead=newnode;//头指针指向新节点的地址
newnode->_next=next;//将未插入之前的头结点的地址,给新节点的next指针
}
}
SListNode* SListFind(SListNode* pHead, DataType x)//数据查找
{
assert(pHead);//判断链表是否为空
while(pHead)//通过循环条件来控制指针的走向,终止条件是指针指向空
{
if(pHead->_data==x)//如果指针指向的节点的数据等于x,就返回pHead
{
return pHead;
}
pHead=pHead->_next;//让指针指向下一个节点
}
return NULL;//如果跳出while循环,表示没有找到,返回NULL
}
void SListInsest(SListNode** ppHead, int pos, DataType x)//指定位置插入
{
if(*ppHead==NULL)//1.链表为空
{
if(pos==1)//如果插入位置为一,合法
{
SListNode* node=BuySListNode(x);
*ppHead=node;
}
else
printf("链表为空,找不到插入位置!\n");
}
else//2.链表不为空
{
int count=0;
SListNode* Newnode=*ppHead;
while(Newnode)//通过循环计算链表的节点个数
{
count++;
Newnode=Newnode->_next;
}
if(pos>1&&pos<=count)//判断插入位置的范围,1.插入位置在中间
{
SListNode* parent=NULL;
SListNode* NEWnode=*ppHead;
while(--pos)//进行循环,找到插入位置
{
parent=NEWnode;//指向前一节点
NEWnode=NEWnode->_next;//指向当前节点
}
SListNode* node=BuySListNode(x);
node->_next=parent->_next;//新节点的next指针指向未插入之前的当前节点的地址
parent->_next=node;//前一节点的next指针指向新节点
}
if(pos==1)//2.插入位置在头部
{
SListNode* newnode=*ppHead;
SListNode* node=BuySListNode(x);
node->_next=newnode;//新节点的next指针指向未插入之前的第一个节点
*ppHead=node;//头指针指向新节点
}
if(pos==count+1)//3.插入位置在尾部
{
SListNode* parent=NULL;
SListNode* NEWNode=*ppHead;
while(NEWNode)//循环找尾
{
parent=NEWNode;//当前节点
NEWNode=NEWNode->_next;//下一节点
}
SListNode* node=BuySListNode(x);
parent->_next=node;//将尾节点的next指针指向新节点
}
else if(pos<1||pos>(count+1))//4.插入位置不合法
{
printf("插入位置不合法");
}
}
}
void SListErase(SListNode** ppHead, int pos)//指定位置节点删除
{
assert(*ppHead);
int count=0;
SListNode* newnoDe=*ppHead;
while(newnoDe)//通过循环计算链表的节点个数
{
count++;
newnoDe=newnoDe->_next;
}
if(1<pos&&pos<count)//1.中间位置删除
{
SListNode* newnnode=*ppHead;
SListNode* parent=NULL;
while(--pos)//循环找删除点
{
parent=newnnode;//上一节点
newnnode=newnnode->_next;//当前节点
}
parent->_next=newnnode->_next;//将上一节点的next指针指向当前节点的下一个节点地址
free(newnnode);//销毁当前节点
newnnode=NULL;//指针置空
}
if(pos==1)//2.删除第一个节点
{
SListNode* nnewnode=*ppHead;
*ppHead=nnewnode->_next;//头指针指向第一个节点的next,
free(nnewnode);//销毁当前节点
nnewnode=NULL;//指针置空
}
if(pos==count)//3。删除尾节点
{
SListNode* newwnode=*ppHead;
SListNode* parent=NULL;
while(--pos)//循环找点
{
parent=newwnode;//前一节点
newwnode=newwnode->_next;//当前节点
}
free(newwnode);//销毁当前节点
parent->_next=NULL;//上一节点的next置空
newwnode=NULL;//指针置空,防止野指针
}
else if(pos<=0||pos>count)//4.删除位置不合法
{
printf("位置不合法!");
}
}
void text()
{
SListNode* pHead=NULL;
SListPushBack(&pHead,1);
SListPushBack(&pHead,2);
SListPushBack(&pHead,3);
SListPopBack(&pHead);
SListPopBack(&pHead);
SListPopBack(&pHead);
SListPushFront(&pHead,1);
SListPushFront(&pHead,2);
SListPushFront(&pHead,3);
SListErase(&pHead,3);
SListDestory(&pHead);
//int ret=SListFind(pHead,2)->_data;
//printf("2? %d\n",ret);
//SListInsest(&pHead,4,4);
SListPrint(pHead);
}
int main()
{
text();
return 0;
}
929

被折叠的 条评论
为什么被折叠?



