提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
前言
对带头节点单链表进行一些基础操作
一、使用尾插法建立单链表
1.方法理解
使用尾插法建立单链,主要是要建立两个节点,一个节点用于存储当前输入数据,另外一个节点要始终指向当前链表的尾部即尾节点。使用尾插法建立链表的数据顺序是键入的数据顺序。
2.代码示例
#include<stdio.h>
#include<stdlib.h>
typedef struct LNode
{
int data;
LNode *next;
}LNode,*LinkList;
void InitList(LinkList*L);
void OutputList(LinkList L);
int main()
{
LinkList L;
InitList(&L);//尾插法建立链表
OutputList(L);
return 0;
}
void InitList(LinkList*L)
{
(*L)=(LNode*)malloc(sizeof(LNode));//带头节点的链表
(*L)->next=NULL;
LNode*s=(*L);//定义一个 指向表尾的指针
LNode*p;//定义一个存储当前数据的指针
int num;
scanf("%d",&num);
while(num!=-1)
{
p=(LNode*)malloc(sizeof(LNode));
p->data=num;
p->next=s->next;
s->next=p;
s=p;//始终将s指针指向最后一个节点
scanf("%d",&num);
}
p->next=NULL;
}
void OutputList(LinkList L)
{
LinkList p=L->next;
while(p)
{
printf("%d\t",p->data);
p=p->next;
}
printf("\n");
}
二、头插法建立单链表
1.方法理解
使用头插法建立单链表,只需要建立一个存储当前数据的节点,其实原理就是在单链表中插入一个节点,但是每次插入的位置都是1,所以使用头插法的链表数据顺序为键入顺序的倒序。
2.代码示例
#include<stdio.h>
#include<stdlib.h>
typedef struct LNode
{
int data;
LNode *next;
}LNode,*LinkList;
void InitList(LinkList*L);
void OutputList(LinkList L);
int main()
{
LinkList L;
InitList(&L);//头插法建立链表
OutputList(L);
return 0;
}
void InitList(LinkList*L)
{
(*L)=(LNode*)malloc(sizeof(LNode));//带头节点的链表
(*L)->next=NULL;
LNode*p;//定义一个存储数据的节点
int num;
scanf("%d",&num);
while(num!=-1)
{
p=(LNode*)malloc(sizeof(LNode));
p->data=num;
p->next=(*L)->next;
(*L)->next=p;
scanf("%d",&num);
}
}
void OutputList(LinkList L)
{
LinkList p=L->next;
while(p)
{
printf("%d\t",p->data);
p=p->next;
}
printf("\n");
}
二、头插法建立单链表
对带头节点的单链表进行增删改操作
代码如下:
#include<stdio.h>
#include<stdlib.h>
typedef struct LNode
{
int data;
LNode *next;
}LNode,*LinkList ;
void InitList(LinkList*L);
void Output(LinkList L);
void InsertList(LinkList*L,int InsertSite,int value);
void DeleList(LinkList *L,int DeleSite);
void DeleList_value(LinkList*L,int value);//删除链表中数值为3的节点
void ChangeList_site(LinkList*L,int ChangeSite,int value);
void ChangeList_value(LinkList*L,int value,int ChangeValue);
int Getlength(LinkList *L);
int main()
{
LinkList L;
InitList(&L);
Output(L);
InsertList(&L,3,5);//在第三个位置插入数值5
Output(L);
DeleList(&L,3);//删除链表的第三个节点
Output(L);
DeleList_value(&L,3);//删除链表中数值为3的节点
Output(L);
ChangeList_site(&L,3,99);//按照节点的位置修改数据
Output(L);
ChangeList_value(&L,2,99);//按照节点的数据修改,将数据为2的节点,改为99
Output(L);
return 0;
}
void InitList(LinkList*L)
{
*L=(LNode*)malloc(sizeof(LNode));
(*L)->next=NULL;
LNode*s;//定义一个存储当前输入数据的节点
LNode*p=(*L);//定义尾节点
int num;
scanf("%d",&num);
while(num!=-1)
{
s=(LNode*)malloc(sizeof(LNode));
s->data=num;
p->next=s;
p=s;
scanf("%d",&num);
}
p->next=NULL;
}
void Output(LinkList L)
{
LinkList p=L->next;
while(p)
{
printf("%d\t",p->data);
p=p->next;
}
printf("\n");
}
void InsertList(LinkList*L,int InsertSite,int value)
{
int flag=1;
int len=0;
len=Getlength(L);
printf("%d\n",len);
if(InsertSite>(len+1)||InsertSite<1)
{
flag=0;
}
if(flag==0)
{
printf("插入失败!\n");
}else{
LNode*q;
q=(LNode*)malloc(sizeof(LNode));
q->data=value;
if(InsertSite==1)
{
q->next=(*L)->next;
(*L)->next=q;
}else
{
int i;
LNode*s=*L;
for(i=1;i<InsertSite;i++)
{
s=s->next;
}
q->next=s->next;
s->next=q;
}
}
}
int Getlength(LinkList* L)
{
int len=0;
LNode *length=(*L)->next;
while(length)
{
len++;
length=length->next;
}
return len;
}
void DeleList(LinkList *L,int DeleSite)
{
int flag=1;
int len=Getlength(L);
if(DeleSite<1||DeleSite>len)
{
flag=0;
}
if(flag==0)
{
printf("删除错误!\n");
}else
{
if(DeleSite==1)
{
LNode*p=*L;
p=p->next;
(*L)->next=p->next;
}else{
LNode*p=*L;//定义一个要删除位置前面一个位置的指针
LNode*q=p->next;//定义一个指向要删除节点的指针
int i;
for(i=1;i<DeleSite;i++)
{
p=p->next;
q=q->next;
}
p->next=q->next;
}
}
}
void DeleList_value(LinkList*L,int value)
{
int flag=0;
int len=Getlength(L);
printf("%d\n",len);
int i;
int count=0;
int cou[len];
LNode*p=(*L)->next;
for(i=1;i<=len;i++)
{
if(p->data==value)
{
flag=1;
cou[count]=i;
count++;
}
p=p->next;
}
printf("%d\n",count);
if(flag==0)
{
printf("删除失败!\n");
}else
{
for(i=0;i<count;i++)
{
printf("%d\t",cou[i]);
}
printf("\n");
for(i=0;i<count;i++)
{
DeleList(L,cou[i]-i);//每删除一个数据,后面的数据的顺序就会减一
}
}
}
void ChangeList_site(LinkList*L,int ChangeSite,int value)
{
int flag=1;
int len=Getlength(L);
if(ChangeSite<1||ChangeSite>len)
{
flag=0;
}
if(flag==0)
{
printf("改变失败!\n");
}else{
LNode*p=(*L);
int i;
for(i=0;i<ChangeSite;i++)
{
p=p->next;
}
p->data=value;
}
}
void ChangeList_value(LinkList*L,int value,int ChangeValue)
{
int flag=0;
int len=Getlength(L);
int i;
int count=0;
int cou[len];
LNode*p=(*L)->next;
for(i=1;i<=len;i++)
{
if(p->data==value)
{
flag=1;
cou[count]=i;
count++;
}
p=p->next;
}
if(flag==0)
{
printf("改变失败!\n");
}else
{
for(i=0;i<count;i++)
{
ChangeList_site(L,cou[i],99);
}
}
}
总结
带头节点的单链表的使用情况很多,熟悉对单链表的增删改查很有必要。在建立指针节点时一定要注意该节点指向什么地方,需不需要重新划分空间给它。同时,循环的条件,以及各种操作的边缘条件也应该考虑清楚。