何为链表呢?
不同于数组,它是储存空间中非连续的储存结构,我们需要用链表中的指针来指向下一个数据元素。而单向链表,顾名思义,也就是只能由结点单向的指向该后继地址的链表。
链表有什么好处呢?
1.可以提高空间的利用率。
2.可以动态储存数据元素。
使用头插法创建单向链表的逻辑思维图如下:
一个链表中应该包含两个域,一个是数据域——用于储存数据元素,一个是指针域——用于指向下一个数据元素的结点地址。
接下来我们来看看如何用代码实现单项链表:
1.首先做好准备工作:
//引入头文件
#include <cstdio>
#include <cstdlib> //后面会用到malloc和free函数
//单向链表
struct Node{
int date; //数据域
struct Node* next; //指针域
}Node;
2.创建表头:
struct Node* createlist() //创建表头
{
struct Node* headlist = (struct Node*)malloc(sizeof(struct Node)); //动态给表头分配内存
headlist->next = NULL; //使表头指向空
return headlist; //返回已经创建好的表头
}
表头数据域为空,该部分创建是逻辑图中的
3.创建结点:
struct Node* createnode(int date) //创建结点
{
struct Node* newlist = (struct Node*)malloc(sizeof(struct Node)); //动态分配
newlist->next = NULL; //使结点的后继指向空
newlist->date = date; //给结点的数据元素赋值
return newlist; //返回该结点
}
该部分使创建逻辑图中的
4.遍历链表并打印链表:
void printlist(struct Node* L)
{
struct Node* move = L->next; //创建转换量
while(move) //遍历
{
printf("%d ",move->date); //打印数据
move = move->next; //移向后一个结点
}
printf("\n");
}
5.将元素插入表头:
void pushflist(struct Node* headlist,int date) //插入表头
{
struct Node* newnode = createnode(date); //创建一个新结点
newnode->next = headlist->next; //使新结点的后继指向表头的后继
headlist->next = newnode; //使表头的后继指向新创建的结点
}
该步骤逻辑思维图:
6.将元素插入表尾:
void pushblist(struct Node* headlist,int date)
{
struct Node* move = headlist->next; //创建一个用于移动的转换量
if(headlist->next == NULL) //如果链表为空
{
headlist->next = createnode(date); //直接将新结点加在表头后
return;
}
while(move->next) //遍历链表,一直到最后一个结点
move = move->next;
move->next = createnode(date); //将新结点加在最后一个结点后面
}
该步骤逻辑思维如下:
7.将链表最后一个元素剔除:
void poplist(struct Node* headlist)
{
struct Node* move = headlist->next; //创建一个可移动的转换量
struct Node* p = NULL; //用于保存被删除的结点的上一个结点
if(headlist->next == NULL) //如果链表为空则直接退出
return;
while(move->next) //遍历链表
{
p = move;
move = move->next;
}
free(move); //将删除的结点释放
p->next = NULL; //使被删除结点的上一个结点的后继指向空
}
该步骤逻辑思维如下:
8.查找:
struct Node* find(struct Node* headlist,int x)
{
struct Node* move = headlist->next; //定义转换量
int y;
while(move) //遍历
{
struct Node* p = move->next;
if(p->date == x)
{
y = x;
printf("yes\n");
return move; //由于打印是从第二个结点开始打印,因此这里返回查找后的上一个结点
}
move = move->next;
}
return;
}
9.主函数测试:
int main()
{
struct Node* headlist = createlist();
pushflist(headlist,8);
pushflist(headlist,2);
pushflist(headlist,3);
printlist(headlist);
pushblist(headlist,456);
printlist(headlist);
poplist(headlist);
printlist(headlist);
struct Node* f = find(headlist,2);
printlist(headlist);
return 0;
}
关于单向链表的研究目前就如上所示,若有更好的解决方式和改进方式可以相互讨论!