- 带头节点链表 好处在于 头节点永远都是固定的
- 初始化链表 struct LinkNode * pHeader = init_LinkList ()
- 遍历链表 void foreach_LinkList( struct LinkNode * pHeader )
- 插入链表 void insertLinkList( struct LinkNode*pHeader , int oldval ,int newval )
- 在oldval前插入 newVal,如果没有oldval就进行尾插
- 删除链表 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 )
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);
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 * nextNode = pCurrent->next;
free(pCurrent);
pCurrent = nextNode;
}
//头节点的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;
}
struct LinkNode * pCurrent = pHeader->next;
int num = 0;
while (pCurrent != NULL)
{
num++;
pCurrent = pCurrent->next;
}
return num;
}
main.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 20 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();
system("pause");
return EXIT_SUCCESS;
}