链表的基本使用
带头节点链表 好处在于 头节点永远都是固定的
- 初始化链表 :
-
struct LinkNode* pHeader =init_LinkList()
- 遍历链表 :
-
void foreach_linkList(struct LinkNode*pHeader)
- 插入链表 :
-
void insert_LinkList(struct LinkNode*pHeader,int oldVal,int newVal);
-
在oldva前插入 newVal,如果没有olval就进行尾插
-删除链表 :
-
void delete_LinkList(struct LinkNode*pHeader, int val)
-
用户提供的有效数据 删除掉
-
无效数据直接 return
-
- 清空链表 :
-
void clear_LinkList(struct LinkNode*pHeader)
-
将所有有数据的节点释放掉
-
- 销毁链表 :
-
void destroy_LinkList(struct LinkNode*pHeader)
-
将整个链表都是放掉
-
反转链表 通过3个辅助指针变量实现链表的翻转
-
统计链表长度 int size_LinkList(struct LinkNode*pHeader)
-
代码示例:
链表的基本使用.c
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include"linkList.h"
void test01()
{
//初始化链表
struct LinkNode*pHeader= init_LinkList();
//表里链表
printf("遍历链表的结果为\n");
foreach_linkList(pHeader);
//插入数据
//100 10 200 30 300
insert_LinkList(pHeader, 10, 100);
insert_LinkList(pHeader, 20, 200);
insert_LinkList(pHeader, -1, 300);
printf("插入数据后,遍历链表的结果为\n");
foreach_linkList(pHeader);
//测试删除
delete_LinkList(pHeader,30);
delete_LinkList(pHeader, 100);
delete_LinkList(pHeader, 1000);
//10 200 20 300
printf("删除数据后,遍历链表的结果为\n");
foreach_linkList(pHeader);
//清空链表
clear_LinkList(pHeader);
printf("清空数据后,遍历链表的结果为\n");
foreach_linkList(pHeader);
insert_LinkList(pHeader,111,111);
insert_LinkList(pHeader, 222, 222);
insert_LinkList(pHeader, 333, 333);
printf("清空后再次使用链表,遍历链表的结果为\n");
foreach_linkList(pHeader);
//销毁链表
destroy_LinkList(pHeader);
pHeader = NULL;
void test02()
{
struct LinkNode*pHeader = init_LinkList();
//10 20 30
//翻转后结果应该为 30 20 10
reverse_LinkList(pHeader);
printf("翻转链表后结果为\n");
foreach_linkList(pHeader);
printf("链表的长度为:%d\n", size_LinkList(pHeader));
}
int main()
{
//test01();
test02();
return EXIT_SUCCESS;
}
linkList.c
#include"linkList.h"
//初始化链表
struct LinkNode*init_LinkList()
{
struct LinkNode*pHeader = malloc(sizeof(struct LinkNode));
if (pHeader == NULL)
{
return NULL;
}
//pHeader->num=-1; 头节点不维护数据域
pHeader->next = NULL;//头结点初始化指针域为NULL
//创建一个尾结点,利于后期添加新的数据
struct LinkNode*pTail = pHeader;
int val = -1;
while (1)
{
printf("请插入数据-1代表输入结束:\n");
scanf("%d", &val);
if (val == -1)
{
break;
}
//创建新节点
struct LinkNode*newNode = malloc(sizeof(struct LinkNode));
newNode->num = val;
newNode->next = NULL;
//建立关系
pTail->next = newNode;
//更新新的尾结点
pTail = newNode;
}
return pHeader;
}
//遍历链表
void foreach_linkList(struct LinkNode*pHeader)
{
if (pHeader == NULL)
{
return;
}
//pCurrent 起始指向的是第一个有真实数据的节点
struct LinkNode*pCurrent = pHeader->next;
while (pCurrent!=NULL)
{
printf("%d\n",pCurrent->num);
pCurrent = pCurrent->next;
}
}
//插入链表
void insert_LinkList(struct LinkNode*pHeader, int oldVal, int newVal)
{
if (pHeader==NULL)
{
return;
}
//创建两个辅助指针变量
struct LinkNode*pPrev = pHeader;
struct LinkNode*pCurrent = pHeader->next;
while (pCurrent !=NULL)
{
if (pCurrent->num==oldVal)//找到插入位置
{
break;
}
//如果没有找到位置,让辅助指针后移
pPrev = pCurrent;
pCurrent = pCurrent->next;
}
//建立新节点
struct LinkNode*newNode = malloc(sizeof(struct LinkNode));
newNode->num = newVal;
newNode->next = NULL;
//建立关系 更新指针的指向
newNode->next=pCurrent;
pPrev->next=newNode;
}
//删除链表
void delete_LinkList(struct LinkNode*pHeader, int val)
{
if (pHeader == NULL)
{
return;
}
//创建两个辅助指针变量
struct LinkNode*pPrve = pHeader;
struct LinkNode*pCurrent = pHeader->next;
while (pCurrent!=NULL)
{
if (pCurrent->num == val)
{
break;
}
pPrve= pCurrent;
pCurrent = pCurrent->next;
}
//无效数据 就直接return
if (pCurrent == NULL)
{
return;
}
//更改指针的指向
pPrve->next = pCurrent->next;
//删除节点
free(pCurrent);
pCurrent = NULL;
}
//清空链表
void clear_LinkList(struct LinkNode*pHeader)
{
if (pHeader == NULL)
{
return;
}
//创建临时指针
struct LinkNode*pCurrent = pHeader->next;
while (pCurrent!=NULL)
{
//先保存住待删除节点的后面的节点
struct LinkNode*nexNode = pCurrent->next;
free(pCurrent);
pCurrent = NULL;
}
//头节点的next置空
pHeader->next = NULL;
}
//销毁链表
void destroy_LinkList(struct LinkNode*pHeader)
{
if (pHeader == NULL)
{
return;
}
//先清空链表
clear_LinkList(pHeader);
//在释放头节点
free(pHeader);
pHeader = NULL;
}
//反转链表
void reverse_LinkList(struct LinkNode*pHeader)
{
if (pHeader==NULL)
{
return;
}
struct LinkNode*pPrve = NULL;
struct LinkNode*pCurrent = pHeader->next;
struct LinkNode*pNext = NULL;
while (pCurrent!=NULL)
{
pNext = pCurrent->next;
pCurrent->next = pPrve;
pPrve = pCurrent;
pCurrent = pNext;
}
pHeader->next = pPrve;
}
//返回链表·长度
int size_LinkList(struct LinkNode*pHeader)
{
if (pHeader == NULL)
{
return -1;
}
struct LinkNode*pCurrent = pHeader->next;
int num = 0;
while (pCurrent!=NULL)
{
num++;
pCurrent = pCurrent->next;
}
return num;
}
linkList.h
#pragma once
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
//节点声明
struct LinkNode
{
int num;//数据域
struct LinkNode*next;//指针域
};
//初始化链表
struct LinkNode*init_LinkList();
//遍历链表
void foreach_linkList(struct LinkNode*pHeader);
//插入链表
void insert_LinkList(struct LinkNode*pHeader,int oldVal,int newVal);
//删除链表
void delete_LinkList(struct LinkNode*pHeader, int val);
//清空链表
void clear_LinkList(struct LinkNode*pHeader);
//销毁链表
void destroy_LinkList(struct LinkNode*pHeader);
//反转链表
void reverse_LinkList(struct LinkNode*pHeader);
//返回链表·长度
int size_LinkList(struct LinkNode*pHeader);