C语言单链表增删查改详解

C语言单链表增删查改详解

单链表 

单链表是一种链式存取的数据结构,用一组地址任意的存储单元存放线性表中的数据元素。链表中的数据是以结点来表示的,每个结点的构成:元素(数据元素的映象) + 指针(指示后继元素存储位置),元素就是存储数据的存储单元,指针就是连接每个结点的地址数据。

单链表的建立编辑

链表操作中动态存储分配要使用标准函数,先介绍一下这些函数。

(1)malloc(size)

在内存的动态存储区申请一个长度为size字节的连续空间。

(2)calloc(n,size)

在内存的动态存储区申请n个长度为size字节的连续空间,函数返回值为分配空间的首地址。若此函数未被成功执行,函数返回值为0。

(3)free(p)

释放由指针p所指向的存储单元,而存储单元的大小是最近一次调用malloc()或calloc()函数时所申请的存储空间。
在头文件\"stdlib.h”中包含了这些函数的信息,使用这些函数时需在程序开头用文件包含指令#include“stdlib.h”指明。
另请读者注意,调用动态存储分配函数返回的指针是指向void类型或char类型的指针,在具体使用时,要根据所指向的数据进行强制类型转换。
单链表的建立有头插法、尾插法两种方法。

1.头插法

单链表是用户不断申请存储单元和改变链接关系而得到的一种特殊数据结构,将链表的左边称为链头,右边称为链尾。头插法建单链表是将链表右端看成固定的,链表不断向左延伸而得到的。头插法最先得到的是尾结点。
由于链表的长度是随机的,故用一个while循环来控制链表中结点个数。假设每个结点的值都大于O,则循环条件为输入的值大于o。申请存储空间可使用malloc()函数实现,需设立一申请单元指针,但malloc()函数得到的指针并不是指向结构体的指针, 需使用强制类型转换,将其转换成结构体型指针。刚开始时,链表还没建立,是一空链表,head指针为NULL。
链表建立的过程是 申请空间、得到数据、建立链接的循环处理过程。

2.尾插法

若将链表的左端固定,链表不断向右延伸,这种建立链表的方法称为尾插法。尾插法建立链表时,头指针固定不动,故必须设立一个搜索指针,向链表右边延伸,则整个算法中应设立三个链表指针,即头指针head、搜索指针p2、申请单元指针pl。尾插法最先得到的是头结点。

代码地址:链接:百度云下载密码:68ni


如图所示:

C语言单链表增删查改详解_第1张图片



单链表的增加节点图解:

C语言单链表增删查改详解_第2张图片


单链表删除图解:

C语言单链表增删查改详解_第3张图片


代码:

/*
单链表:有表头:首节点:数据域没有值,只有一个指针域
---->结构体
1.创建表
2.创建结点
3.插入(表头,指定位置,表尾)
4.删除(表头,指定位置,表尾)
5.判断是否为空
6.打印
*/
#include 
using namespace std;
/*
创建结点结构体
*/
typedef struct SingleList
{
	//数据域--->存储的数据类型
	int data;
	//指针域--->结构体类型的指针
	struct SingleList* next;
}SINGLELIST, *LPSINGLELIST;
//typedef: 定义别名
//struct SingleList  :SINGLELSIT
//struct SingleList* :*LPSINGLELIST
/*
声明你要做的事情
*/
//创建一个表---->返回一个表
LPSINGLELIST CreateList();//实质是创建没有data的节点
//创建节点---->返回一个Node
LPSINGLELIST CreateNode(int data);//创建结点要传入数据
//判断是否为空
int IsEmptyList(LPSINGLELIST L);//为空返回1,不为空返回0
//打印
void PrintList(LPSINGLELIST L);//循环遍历打印
//插入
void InsertListHeadNode(LPSINGLELIST L, int data);
void InsertListTailNode(LPSINGLELIST L, int data);
void InsertListAppoinNode(LPSINGLELIST L, int data, int item);
//删除
void DeleteListHeadNode(LPSINGLELIST L);
void DeleteListTailNode(LPSINGLELIST L);
void DeleteListAppoinNode(LPSINGLELIST L, int item);

int main()
{
	//创建链表L
	LPSINGLELIST L = CreateList();
	//测试头插法 3 2 1
	InsertListHeadNode(L, 1);
	InsertListHeadNode(L, 2);
	InsertListHeadNode(L, 3);
	//测试表位插入 5 6 7
	InsertListTailNode(L, 5);
	InsertListTailNode(L, 6);
	InsertListTailNode(L, 7);
	//测试指定位置插入 3  2  1 4 5 6 7
	InsertListAppoinNode(L, 4, 5);

	//删除头
	DeleteListHeadNode(L);
	PrintList(L);

	//删除尾部
	DeleteListTailNode(L);
	PrintList(L);

	DeleteListAppoinNode(L, 4);
	PrintList(L);
	return 0;
}
//-------------->创建表
LPSINGLELIST CreateList()
{
	//为链表分配空间
	LPSINGLELIST L = (LPSINGLELIST)malloc(sizeof(SINGLELIST));//作业用new
	//指针域置空
	if (L == NULL)
	{
		cout << "内存分配失败" << endl;
		return NULL;
	}
	//表头没有数据
	L->next = NULL;
	return L;
}
//-------------->创建节点
LPSINGLELIST CreateNode(int data)
{
	//为Node分配空间
	LPSINGLELIST Node = (LPSINGLELIST)malloc(sizeof(SINGLELIST));//作业用new
	//指针域置空
	if (Node == NULL)
	{
		cout << "内存分配失败" << endl;
		return NULL;
	}
	//节点数据域的初始化
	Node->data = data;
	//节点指针域的初始化
	Node->next = NULL;
	return Node;
}

int IsEmptyList(LPSINGLELIST L)
{
	//只有表头节点的时候, 为空
	if (L->next == NULL)//容易出错,容易些赋值表达式
		return 1;//返回1为空
	else
		return 0;//返回0不为空
}
//CreateList和CreateNode都必须判断是否为空
//遍历和打印
void PrintList(LPSINGLELIST L)
{
	//判断是否为空
	if (IsEmptyList(L))
		throw 1;
	LPSINGLELIST p = L->next;//因为表头没有数据
	while (p)
	{
		cout << " " << p->data;
		p = p->next;	//递推 i=i+1是一样
	}
	cout << endl;
}

//----------->插入表头
void InsertListHeadNode(LPSINGLELIST L, int data)
{
	//创建节点
	LPSINGLELIST Node = CreateNode(data);
	//先连接在打断
	Node->next = L->next;
	L->next = Node;
}
//---------->表位插入
void InsertListTailNode(LPSINGLELIST L, int data)
{
	//创建节点
	LPSINGLELIST Node = CreateNode(data);
	//找到尾节点
	//误区:最后一个结点不是指NULL,指NULL的上一个结点
	LPSINGLELIST p = L;
	while (p->next != NULL)
		p = p->next;
	p->next = Node;
}
//----------->指定位置插入
void InsertListAppoinNode(LPSINGLELIST L, int data, int item)
{
	//创建节点
	LPSINGLELIST Node = CreateNode(data);
	//讲的是2个指针
	//回去尝试一个指针
	LPSINGLELIST q = L;
	LPSINGLELIST k = L->next;
	while (k->data != item)
	{
		//q和k一直保持相邻,
		q = k;
		k = q->next;

		//未找到
		if (k == NULL)
		{
			cout << "未找到插入位置" << endl;
			return;
		}
	}
	//list 排序,有交叉插入 1 3 5 7 9   2 4 6   ===1 2 3 4 5 6 7 9
	q->next = Node;
	Node->next = k;
}
//----------->删除头
void DeleteListHeadNode(LPSINGLELIST L)
{
	//判断是否为空
	if (IsEmptyList(L))
		exit(0);
	LPSINGLELIST p = L->next;
	L->next = p->next;
	free(p);
}
//------------>删除尾节点
void DeleteListTailNode(LPSINGLELIST L)
{
	//判断是否为空
	if (IsEmptyList(L))
		exit(0);
	LPSINGLELIST q = L;
	LPSINGLELIST p = q->next;
	while (p->next)
	{
		q = p;
		p = q->next;
	}
	q->next = NULL;
	free(p);
}
void DeleteListAppoinNode(LPSINGLELIST L, int item)
{
	//判断是否为空
	if (IsEmptyList(L))
		exit(0);
	LPSINGLELIST q = L;
	LPSINGLELIST p = L->next;
	//找到删除的节点p;
	while (p->data != item)
	{
		q = p;
		p = q->next;
		if (p == NULL)
		{
			cout << "未找到指定位置" << endl;
			return;
		}
	}
	q->next = p->next;
	free(p);
}

多多指教。。。

你可能感兴趣的:(编程语言C语言)