单链表:本质是通过指针来将结构体变量和结构体变量之间连接到一起。
结构与结构体相似,声明如下:
//单链表 1.0
struct Node //结构体原型 (跟结构体长得一样,区别在于:存在一个 指向自身的指针型成员。
{
int data;//数据域
struct Node *next;//指针域 :指向下一节点
};
动态创建一个链表的工作分为:
1、动态内存申请
2、模块设计
步骤:
1、创建表头,表示整个链表
struct Node *creat()//创建链表表头
{
struct Node *headnode=(struct Node *)malloc(sizeof(struct Node));//进行动态申请
headnode->next=NULL;//变量试用前先初始化
return headnode;
}
2、创建结点
struct Node *add(int data)//创建节点
{
struct Node *newnode=(struct Node *)malloc(sizeof(struct Node ));//进行动态申请
newnode->data=data;//变量试用前先初始化
newnode->next=NULL;
return newnode;
}
打印链表图示:
代码实现:
相当于调用函数进行打印
void print(struct Node *headnode)
{
struct Node *move=headnode->next;
while(move)
{
printf("%d ",move->data);
move=move->next;
}
printf("\n");
}
(对链表搞点操作)
3、结点的<插入>
图示:
先处理新结点的指针域(指向原链表头的next结点),再处理链表头的指针域(指向新结点)
反过来会造成程序进入死循环。
由于每次插入位置位于head与原head->next之间,故实际上链表储存数据的顺序与操作顺序相反。
void insert(struct Node *headnode,int data)//插入节点与对应数据
{
struct Node *newnode=add(data);/*这里调用了创建新结点的函数,
即每执行一个新的插入程序,都先创建一个新结点来储存传入的data。同时,
将新结点利用简单的改变指针指向来实现插入到head结点和原head->next之间。*/
newnode->next=headnode->next;//以下两行为核心功能代码
headnode->next=newnode;
}
int main()
{
struct Node *list=creat();
insert(list,1);
insert(list,2);
insert(list,3);
print(list);
}
4、结点的<删除>:
主要思路:
1 判断是否为目标数据
是 否
2 进行图示操作删除该结点 沿链表向下推移
3 再次执行1-3的循环
4 到最后一项,则改链表无目标数据
图示:
代码实现:
void deletei(struct Node *headnode,int posdata)
{
//以下两行将head与head->next分别
赋值给posnodefront与posnode
struct Node *posnode=headnode->next;
struct Node *posnodefront=headnode;
if(posnode==NULL)//如果改链表为空链表(即head后不是NULL),则输出不太行
{
printf("不太行");
}
else//如果不是空链表
{
while(posnode->data!=posdata)/*不是目标数据,则
将posnodefront与posnode沿着链表向下一结点推移*/
{
posnodefront=posnode;
posnode=posnode->next;
if(posnode==NULL)//推移到最后一项结点(即尾指针指向NULL)都未找到则输出“未找到”
{
printf("未找到");
break;
}
}
posnodefront->next=posnode->next;//找到目标数据,则通过改变指针指向来实现改结点的跳出
free(posnode); //对跳出的结点进行释放空间,完成删除
}
}
5、结点的<查找>
struct Node *Find(struct Node *headnode,int dataf)
{
if (headnode==NULL)
{
return NULL;
}
struct Node *fin=headnode;
while (fin)
{
if (fin->data==dataf)
{
return fin;
}
else
{
fin=fin->next;
}
}
return NULL;
}
6、结点的<修改>
由于无法直接访问单链表内指定的结点,在修改指定结点的值时采用 “先查找 后赋值” 的办法。
struct Node *change(struct Node *headnode,int w,int n)/*传入参数为
需要修改的目标单链表,需要修改的原数据,修改后的新数据*/
{
if (headnode==NULL)
{
return NULL;
}
struct Node *cha=headnode;//保存链表头,用于打印或返回
while (headnode)
{
if (headnode->data==w)
{
headnode->data=n;//查找到对应的原数据后进行新数据的赋值
}
else
{
headnode=headnode->next;//未找到,则沿着单链表向下一结点推进
}
}
return cha;//返回表头
}
最后附上一张完整的代码:
//单链表 1.0
#include <stdio.h>
#include <stdlib.h>
struct Node //结构体原型 (跟结构体长得一样,区别在于:存在一个 指向自身的指针型成员。
{
int data;//数据域
struct Node *next;//指针域 :指向下一节点
};
struct Node *creat();//创建表头
struct Node *add(int data);//创建节点
void insert(struct Node *headnode,int data);//头插
void tail(struct Node *headnode,int data);//尾插
void deletei(struct Node *headnode,int posdata);//删除
struct Node *change(struct Node *headnode,int w,int n); //修改
void print(struct Node *headnode);//打印
struct Node *creat()//创建链表表头
{
struct Node *headnode=(struct Node *)malloc(sizeof(struct Node));
headnode->next=NULL;
return headnode;
}
struct Node *add(int data)//创建节点
{
struct Node *newnode=(struct Node *)malloc(sizeof(struct Node ));
newnode->data=data;
newnode->next=NULL;
return newnode;
}
void insert(struct Node *headnode,int data)//头插:插入节点与对应数据
{
struct Node *newnode=add(data);
newnode->next=headnode->next;
headnode->next=newnode;
}
void tail(struct Node *headnode,int data)//尾插
{
if(headnode->next==NULL)
{
headnode->next=add(data);
return;
}
struct Node *p=headnode;
while(p->next)
{
p=p->next;
}
p->next=add(data);
}
void deletei(struct Node *headnode,int posdata)//删除
{
struct Node *posnode=headnode->next;
struct Node *posnodefront=headnode;
if(posnode==NULL)
{
printf("不太行");
}
else
{
while(posnode->data!=posdata)
{
posnodefront=posnode;
posnode=posnode->next;
if(posnode==NULL)
{
printf("未找到");
break;
}
}
posnodefront->next=posnode->next;
free(posnode);
}
}
struct Node *change(struct Node *headnode,int w,int n)//修改
{
if (headnode==NULL)
{
return NULL;
}
struct Node *cha=headnode;
while (headnode)
{
if (headnode->data==w)
{
headnode->data=n;
}
else
{
headnode=headnode->next;
}
}
return cha;
}
void print(struct Node *headnode)//打印
{
struct Node *move=headnode->next;
while(move)
{
printf("%d ",move->data);
move=move->next;
}
printf("\n");
printf("\n");
}
int main()
{
struct Node *list=creat();
insert(list,1);
insert(list,2);
insert(list,3);
insert(list,4);
insert(list,5);
print(list);
tail(list,2);
tail(list,3);
tail(list,4);
print(list);
change(list,3,8);
print(list);
return 0;
}
运行结果如下(采用dev_c++):