创建单链表结构体:
#include<stdio.h>
#include<stdlib.h>
//此处定义的是单链表的单个节点的结构体
typedef struct Node{
int data; //单链表所存的数据类型和数据
struct Node* next; //定义该节点的指针
}Node;
建立一个个节点通过指针相连组成单链表
//初始化链表操作,即创建一个单节点使其data区和指针都置空
Node* initList(){
Node* list=(Node*)malloc(sizeof(Node)); //分配一个Node大小的空间
list->data=0;
list->next=NULL;
return list;
}
函数返回值的类型是Node*,这里我是这样理解的:
typedef一个Node时,相当于在内存中申请了一块两个连续的空间储存data和指向下一个节点的指针,跟 arr 数组分配两个空间类似,数组又跟指针密不可分,所以就用Node*来表示一个链表(实际只是指向这个链表的头)。
![有谁可以告诉我怎么旋转图片吗。。。](https://img-blog.csdnimg.cn/5fb82f3bb28d400eb9cc301da4e0e162.png)
单链表的相关操作
1.头插法
void headInsert(Node* list , int data){
Node* node=(Node*)malloc(sizeof(Node)); //创建新的节点node
node->data=data; //将输入的data值保存至新节点的data区
node->next=list->next; //node的指针指向的是 list头节点的指针 所指
list->next=node; //list头节点的指针指向新节点
list->data++; //list的data区计数+1
}
这里要说明一下,一个单链表的第一个节点通常不用来存储数据,而是记录这个单链表上一共有多少个节点(就像是一本书的第一页先介绍一样,方便后来的人来查明)。
附上图示:
2.尾插法
与头插法类似
不同的是,头插法我们可以很方便的找到头节点并实现头插的操作,尾插法需要我们找到尾节点,即找到一个节点指向NULL
void tailInsert(Node* list,int data){
Node* head=list; //head存储头节点
Node* node=(Node*)malloc(sizeof(Node)); //创建新的节点空间
node->data=data; //新节点data区存储data
node->next=NULL; //指针置空
list=list->next; //直接从头节点的下一个开始
while(list->next){ //当节点指针指向非空时循环开始/继续,直至为NULL
list=list->next;
}
list->next=node; //找到最后一个节点,并将尾节点指向新建节点
head->data++; //计数器+1
}
3.删除某个节点
在已知单链表和所需要删的数据的情况下,遍历单链表:
void delete(Node* list,int data){
Node* pre =list; //pre在current之前,存储 要删除节点之前的 节点的 信息
Node* current=list->next; //current指针
while(current){
if(current->data==data) { //找到了
pre->next=current->next; //删除节点之前的节点的指针指向删除节点之后的节点
free(current); //释放删除节点内存
break; //找到了就中断循环
}
pre=current;
current=current->next; //current和pre指针依次向后判断
}
list->data--; //头节点计数-1
}
4.打印单链表
void printList(Node* list){
list=list->next;
while(list){
printf("%d",list->data);
list=list->next;
}
printf("\n");
}
int main(){
Node* list=initList(); //初始化链表,即建立一个空节点
headInsert(list,1); //头插插入1
/***
。
。
。
需要啥操作就加入对应的函数和值就行
***/
return 0;
}