c语言实现单链表的插入、删除、查找和遍历功能,逆序功能稍等
链表最难的就是指针的操作,所以要多画一下,然后对照图写代码实现功能,才能增进对链表的理解
原理如图:
代码实现如下:
/*单链表*/
#include <stdio.h>
#include <stdlib.h>
typedef int T;
typedef struct node{ /* 1 节点类型定义 */
T data;
struct node* next;
}Node;
#define SIZE sizeof(Node)
/*3 添加节点到链表末尾*/
void add(Node* h,T d){/*头节点地址,新节点数据*/
if(h == NULL){
printf("空链表,添加失败!\n");
return;
}
Node* p = h; //p指向链表头
//3.1 创建新节点并赋值
Node* pn = malloc(SIZE);
pn->data = d;
pn->next = NULL;
//3.2 找到链表的尾节点
while(1){
if(p->next == NULL)
break;
p = p->next;
}
//while(p) p = p->next; 不能
//while(p->next) p = p->next; 可以
//while(p = p->next);
//3.3 把新节点连接到尾节点
p->next = pn;
printf("add success!\n");
}
/*4。遍历链表*/
void travel(Node* h){
//4.1 保存头节点地址
Node* p = h;
//4.2 循环后挪
printf("list:");
while(p->next != NULL){
p = p->next;//先挪后打印 p->next!=NULL 头节点不打印
//4.3 打印当前节点数据
printf("%d ",p->data);
//p = p->next;//先打印后挪 p != NULL 头节点打印
}
printf("\n");
}
/*5 插入节点到指定位置*/
void insert(Node* h,int n,T d){
int i;
//5.1 p指向要插入节点的前一个节点
Node* p = h;
for(i = 0;i < n-1;i++){
p = p->next;
if(p == NULL){
printf("没有位置插入,insert error!\n");
return;
}
}
if(p->next == NULL){
add(h,d);
return;
}
//5.2 创建新节点
Node* pn = malloc(SIZE);
pn->data = d;
//pn->next = NULL;
//5.3 新节点连接p->next节点
pn->next = p->next;
//5.4 p->next指向新节点
p->next = pn;
}
/*6 返回某个位置的节点地址*/
Node* getpos(Node* h,int n){
int i;
Node* p = h;
for(i=0;i<n;i++){
if(p == NULL){
printf("getpos error!\n");
return NULL;
}
p = p->next;
}
return p;
}
/*7 调用getpos的insert*/
void g_insert(Node* h,int n,T d){
Node* p = getpos(h,n-1);
if(p == NULL)
return;
if(p->next == NULL){
add(h,d);
return;
}
Node* pn = malloc(SIZE);
pn->data = d;
pn->next = p->next;
p->next = pn;
}
/*8 修改某个位置上的数据为新的数据*/
void set(Node* h,int n,T d){
//8.1 p指向要修改的节点
Node* p = getpos(h,n);
if(p == NULL){
printf("找不到节点!\n");
return;
}
//8.2 修改数据
p->data = d;
}
/*9 删除某个节点*/
void delpos(Node* h,int n){
//找到要删除的节点的前一个节点
Node* pb = getpos(h,n-1);
if(pb == NULL){
printf("找不到节点!\n");
return;
}
//找到要删除的节点
Node* pd = pb->next;
if(pd == NULL){
printf("找不到节点!\n");
return;
}
//判断要删除的节点是否是尾节点
if(pd->next == NULL){
pb->next = NULL;
printf("删除尾节点!\n");
free(pd);
pd = NULL;
return;
}
//要删除的节点不是尾节点
pb->next = pd->next;//pb->next = pb->next->next;
pd->next = NULL;
free(pd);
pd = NULL;
return;
}
int main(){
/*2 创建头节点*/
Node* head = NULL; //2.1 定义指针
head = malloc(SIZE);//2.2 分配内存
head->data = 0; //2.3 赋值
head->next = NULL;
travel(head);
add(head,8);
add(head,7);
add(head,99);
travel(head);
insert(head,3,666);
travel(head);
g_insert(head,4,444);
travel(head);
set(head,4,888);
travel(head);
delpos(head,3);
travel(head);
delpos(head,4);
travel(head);
return 0;
}
还有注意结构体对于节点创建 ,节点内存空间的开辟,还有就是对于节点的释放都是要注意的。