三、C语言实现头指针的单链表

三、C语言实现头指针的单链表

1、逻辑图

头指针会使用到二级指针

在这里插入图片描述

使用二级指针的逻辑图

在这里插入图片描述

2、声明

#pragma once
//结构声明
typedef int DataType;

typedef struct Node
{
	DataType data;    //记录本结点的数据
	struct Node* next;//记录下一个结点的地址

}Phead_List;

//方法声明

//初始化
bool InitPheadList(Phead_List** p);
//判空
bool IsEmpty(Phead_List** p);
//求长度
int GetLength(Phead_List** p);
//开辟新结点
static Phead_List* ApplyNewNode(DataType value, Phead_List* next);
//头插法
bool InsertOfHead(Phead_List** p, DataType value);
//按位置插入
bool InsertOfPos(Phead_List** p, DataType value, int pos);
//尾插法
bool InsertOfRear(Phead_List** p, DataType value);
//头删
bool DeleteOfHead(Phead_List** p);
//尾删
bool DeleteOfRear(Phead_List** p);
//删除元素(按位置删除)
bool DeleteOfPos(Phead_List** p, int pos);
//输出
void ShowList(Phead_List** p);
//销毁
void DestoryList(Phead_List** p);

3、方法实现

#include<stdio.h>
#include<stdlib.h>
#include"Phead_List.h"

//函数实现

//初始化
bool InitPheadList(Phead_List** p)
{
	//传参时,p的值就是主函数中的Phead地址

	if (p == NULL) return false;

	*p = NULL; //指向头结点的指针置空
}

//判空
bool IsEmpty(Phead_List** p)
{
	if (p == NULL) return false;

	if (*p == NULL) return true;

	return false;
}
//求长度
int GetLength(Phead_List** p)
{
	if (p == NULL) exit(0);
	
	int count = 0;
	Phead_List* q = *p;
	while (q != NULL)
	{
		count++;
		q = q->next;
	}

	return count;
}

//开辟新结点
static Phead_List* ApplyNewNode(DataType value,Phead_List *next)
{
	Phead_List* newspace = (Phead_List*)malloc(sizeof(Phead_List));

	if (newspace == NULL) exit(0);

	newspace->data = value;
	newspace->next  = next;

	return newspace;
}


//头插法
bool InsertOfHead(Phead_List** p, DataType value)
{
	if (p == NULL) return false;

	Phead_List* newnode = ApplyNewNode(value, *p);
	
	*p = newnode;

	return true;
}

//按位置插入
bool InsertOfPos(Phead_List** p, DataType value, int pos)
{
	if (p == NULL) return false;

	if (pos<0 || pos>GetLength(p)) return false;

	//当pos为0时,需特殊处理,改用头插,以为此时要修改头指针的值
	if (pos == 0) return InsertOfHead(p, value);

	//先找到pos位置
	Phead_List* q = *p; //记录第一个结点地址

	while (pos>1)  //找到pos位置的前一个结点
	{
		q = q->next;
		pos--;
	}

	Phead_List* newnode = ApplyNewNode(value, q->next);
	q->next = newnode;

	return true;
}

//尾插法
bool InsertOfRear(Phead_List** p, DataType value)
{
	if (p == NULL) return false;

	return InsertOfPos(p, value, GetLength(p));
}

//头删
bool DeleteOfHead(Phead_List** p)
{
	if (p == NULL) return false;
	if (IsEmpty(p)) return false;

	Phead_List* q = *p;
	*p = q->next;
	free(q);
	q = NULL;

	return true;
}

//尾删
bool DeleteOfRear(Phead_List** p)
{
	if (p == NULL) return false;
	if (IsEmpty(p)) return false;

	Phead_List* q = *p;
	Phead_List* front = NULL;//保存q的前驱节点
	while (q->next!=NULL)
	{
		front = q;
		q = q->next;
	}


	//如果只剩一个结点
	if (front == NULL) return DeleteOfHead(p);
	
	front->next = NULL;
	free(q);
	q = NULL;

	return true;
}

//删除元素(按位置删除)
bool DeleteOfPos(Phead_List** p, int pos)
{
	if (p == NULL) return false;

	if (pos<0 || pos>GetLength(p) - 1) return false;

	if (IsEmpty(p)) return false;

	if (pos == 0) return DeleteOfHead(p);

	if (pos == GetLength(p) - 1) return DeleteOfRear(p);

	//同样找到要删除的pos的前驱结点
	Phead_List* q = *p;        //保存头结点地址
	
	while (pos>1)
	{
		q = q->next;
		pos--;
	}

	Phead_List* s = q->next;  //保存q的后继节点(要删除的结点)
	q->next = s->next;
	free(s);
	s = NULL;

	return true;
}

//输出
void ShowList(Phead_List** p)
{
	if (p == NULL) exit(0);

	Phead_List* q = *p;

	while (q != NULL)
	{
		printf("%d ", q->data);
		q = q->next;
	}

	printf("\n");
}

//销毁
void DestoryList(Phead_List** p)
{
	if (p == NULL) exit(0);

	while (!IsEmpty(p))
	{
		DeleteOfHead(p);   //头删时间复杂度为O(1)
	}

}

4、主函数测试

#include<stdio.h>
#include"Phead_List.h"

int main()
{
	//在栈区
	Phead_List* phead;//头指针,保存第一个结点的地址
	//初始化
	InitPheadList(&phead);

	//头、尾、头插入
	InsertOfHead(&phead, 56);
	InsertOfRear(&phead, 34);
	InsertOfHead(&phead, 78);
	ShowList(&phead);

	//按位置插
	InsertOfPos(&phead, 66, 3);
	InsertOfPos(&phead, 43, 2);
	ShowList(&phead);

	//尾、头删
	DeleteOfRear(&phead);
	DeleteOfHead(&phead);
	ShowList(&phead);

	//按位置删除
	DeleteOfPos(&phead, 2);
	ShowList(&phead);

	DestoryList(&phead);
	return 0;
}

5、测试结果
在这里插入图片描述

6、在实现插入和删除元素时注意考虑多种情况

插入情况

在这里插入图片描述

删除情况
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值