单链表(完整版)

#include <stdio.h>
#include <malloc.h>
/*
	xxx管理系统
	1.先写链表
*/
//节点描述
struct Node 
{
	int data;				//数据域
	struct Node* next;		//指针域
};
//1.创建表头  ---->结构体变量
struct Node* createHead() 
{
	struct Node* headNode = (struct Node*)malloc(sizeof(struct Node));
	//headNode->data=?  表头不存放数据 称之为有头链表
	headNode->next = NULL;
	return headNode;
}
//2.创建节点--->为插入做准备---->需要把用户的数据变成一个节点
struct Node* createNode(int data) 
{
	struct Node* newNode = (struct Node*)malloc(sizeof(struct Node));
	newNode->next = NULL;
	newNode->data = data;
	return newNode;
}
//3.插入
//3.1 插入: 表头插入
void insertByHead(struct Node* headNode, int data) 
{
	struct Node* newNode = createNode(data);	//调用上面自己写的函数把用户的数据变成结构体变量
	//一定是链接 后断开
	newNode->next = headNode->next;
	headNode->next = newNode;
}
//3.2 表尾插入-->找到表尾
void insertByTail(struct Node* headNode, int data) 
{
	//先走到最后一个节点的位置
	struct Node* pMove = headNode;
	while (pMove->next != NULL) 
	{
		pMove = pMove->next;
	}
	struct Node* newNode = createNode(data);
	pMove->next = newNode;
}
//3.3 指定位置插入
void insertByAppoin(struct Node* headNode, int data, int posData)
{
	struct Node* posNode = headNode->next;   //第二个节点
	struct Node* posLeftNode = headNode;	 //第一个节点
	//空链表,以及没有找的状况
	//NULL->data 这种方式错误
	while (posNode != NULL && posNode->data != posData)  //这两个条件不能交换
	{
		posLeftNode = posNode;
		posNode = posNode->next;
		//posNode = (*posNode).next;
	}
	if (posNode != NULL)
	{
		struct Node* newNode = createNode(data);
		posLeftNode->next = newNode;
		newNode->next = posNode;
	}
	else 
	{
		printf("未找到相关位置,无法插入!\n");
		return;
	}
}
//4.删除
//4.1 表头删除
void deleteByHead(struct Node* headNode) 
{
	//deleteNode指向删除的头节点
	struct Node* deleteNode = headNode->next;
	if (deleteNode == NULL) 
	{
		printf("无法删除,链表为空\n");
		return;
	}
	else 
	{
		headNode->next = deleteNode->next;
		free(deleteNode);
		deleteNode = NULL;	//养成置为空的习惯
	}
}
//4.2 表尾删除
void deleteTail(struct Node* headNode) 
{
	struct Node* pTailNode = headNode;
	struct Node* pTailLeft = NULL;
	while (pTailNode->next != NULL) 
	{
		pTailLeft = pTailNode;
		pTailNode = pTailLeft->next;
	}
	if (pTailLeft == NULL) 
	{
		printf("链表为空无法删除!\n");
	}
	else 
	{
		pTailLeft->next = NULL;
		free(pTailNode);
		pTailNode = NULL;
	}
}
//4.3 指定位置删除
void deleteAppoin(struct Node* headNode, int posData)
{
	struct Node* posLeftNode = headNode;
	struct Node* posNode = headNode->next;
	while (posNode != NULL && posNode->data != posData) 
	{
		posLeftNode = posNode;
		posNode = posLeftNode->next;
	}
	if (posNode == NULL) 
	{
		printf("未找到相关位置,无法删除\n");
	}
	else 
	{
		posLeftNode->next = posNode->next;
		free(posNode);
		posNode = NULL;
	}
}
//5.释放内存
void deleteList(struct Node* headNode)
{
	struct Node* nextNode = headNode->next;
	while (nextNode != NULL) 
	{
		headNode->next = nextNode->next;
		free(nextNode);
		nextNode = headNode->next;
	}
}
//4.3 指定位置删除
//5.遍历(访问每个节点数据)
void printList(struct Node* headNode) 
{
	//打印: 有头链表: 应该是从第二个节点打印
	//第二个节点又叫做表头的下一个
	struct Node* pMove = headNode->next;
	while (pMove != NULL) 
	{
		printf("%d\t", pMove->data);
		pMove = pMove->next;			//移动到下一个
	}
	printf("\n");
}
int main() 
{
	struct Node* list = createHead();		//创建链表
	for (int i = 1; i <= 3; i++)		//321123
	{
		insertByHead(list, i);
	}
	printList(list);
	for (int i = 1; i <= 3; i++)
	{
		insertByTail(list, i);
	}
	printList(list);
	insertByAppoin(list, 100, 1);
	printList(list);
	deleteByHead(list);
	printList(list);
	deleteTail(list);
	printList(list);
	deleteAppoin(list, 2);
	printList(list);
	deleteAppoin(list, 2);
	printList(list);
	deleteList(list);
	printList(list);
	free(list);
	list = NULL;
	return 0;
}
上一篇:链表之单循环链表


下一篇:线性表的链式存储--单链表