链表的基本使用

  1. 带头节点链表 好处在于 头节点永远都是固定的
  2. 初始化链表  struct LinkNode * pHeader = init_LinkList ()
  3. 遍历链表   void  foreach_LinkList( struct LinkNode * pHeader )
  4. 插入链表   void insertLinkList( struct LinkNode*pHeader , int oldval ,int newval )
    1. 在oldval前插入  newVal,如果没有oldval就进行尾插
  5. 删除链表  void delete_LinkList( struct LinkNode*pHeader, int val )
    1. 用户提供的有效数据 删除掉
    2. 无效数据 直接return
  6. 清空链表
    1. void clear_LinkList(struct LinkNode*pHeader ) 
    2. 将所有有数据的节点释放掉
  7. 销毁链表
    1. void destroy_LinkList(struct LinkNode*pHeader)
    2. 将整个链表都释放掉
  8. 反转链表
    1. 通过3个辅助指针变量实现链表的翻转
  9. 统计链表长度 
    1. 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;
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值