链表的使用

目录

目录

1.链表的基本概念

2.创建单链表

3.插入结点(头部插入法)

4.遍历链表

5.链表结点的删除

6.链表的释放

7.翻转链表

8.双向链表


一,链表的基本概念

什么是链表?

其实就是很多个相同类型结构体成线性排列,“串”在一起,形成一条链,叫做链表。

怎么做到结构体和结构体之间能“串”在一起?

链表中的每个结构体都相当于一个结点,我们创建的结构体,分为两块区域,

一块叫数据域用于存储我们想存放的信息,

另一块叫指针域,用于存放下一个结点的地址(这样才能访问下一个结点,乃至整条链表)

比如我现在创建了一个结构体,如下

typedef struct Node
{
	int data;//数据域
	struct Node* next;//指针域
}Node;

我们要将若干个相同的结构体串联成如下效果 

静态链表的使用,利于理解上图

struct Node
{
	int data;
	struct Node* next;
};

void test()
{
	struct Node node1 = { 1,NULL };
	struct Node node2 = { 2,NULL };
	struct Node node3 = { 3,NULL };
	struct Node node4 = { 4,NULL };
	struct Node node5 = { 5,NULL };

	node1.next = &node2;
	node2.next = &node3;
	node3.next = &node4;
	node4.next = &node5;

	//遍历列表
	struct Node* pCurrent = &node1;
	while (pCurrent)
	{
		printf("%d\n", pCurrent->data);
		pCurrent = pCurrent->next;
	}


}



int main()
{
	test();
	return 0;
}

二,创建单链表

创建一个单链表,相当于创造一个作为头的结点,头结点后的链表身,属于链表插入的内容

Node* creathead()
{
	Node* headnode = (Node*)malloc(sizeof(Node));//创建一个指针,要么初始化,要么制空
	if (headnode == NULL)
	{
		printf("创建头节点失败\n");
		exit(0);
	}
	headnode->next = NULL;
	return headnode;
}

这样我们就创建好了头结点,然后把头结点的地址返回主函数,有了头结点的地址就可以访问整个链表

三,插入结点(头部插入法)

 (借用一下其他博主的图)

Node* creatnode(int input)
{
	Node* node = (Node*)malloc(sizeof(Node));
	if (node == NULL)
	{
		printf("添加数据失败\n");
		exit(0);
	}
	node->data = input;
	node->next = NULL;
	return node;
}

四,遍历链表

void PrintNode(Node* headnode)
{
	Node* pMove = headnode->next;//定义一个辅助指针,用于遍历
	while (pMove)
	{
		printf("%d\n", pMove->data);
		pMove = pMove->next;
	}

}

五,链表结点的删除

void DelectNode(Node* headnode)
{
	int input = 0;
	scanf("%d", &input);
	Node* pMove = headnode;//定义一个辅助指针,用于遍历
	while (pMove->next != NULL && pMove->next->data != input)//这里不能调换顺序!
	{                                                        //要先判断pMove->next是否为NULL,
		pMove = pMove->next;                                 //再判断pMove->next->data,
	}                                                        //否则就读取了空指针的data,会报错!
                                                              
	if (pMove->next == NULL)
	{
		printf("该结点不存在\n");
		exit(0);
	}

	Node* d = pMove->next;
	pMove->next = pMove->next->next;
	free(d);
	printf("该结点已删除\n");
}

六,释放链表

void FreeNode(Node* headnode)
{
	Node* pMove = headnode;
	Node* pfree = pMove;
	while (pMove != NULL)
	{
		pMove = pMove->next;
		free(pfree);
		pfree = pMove;

	}

	printf("链表已释放成功\n");
}

最后是全部源代码

typedef struct Node
{
	int data;
	struct Node* next;
}Node;

Node* creathead()
{
	Node* headnode = (Node*)malloc(sizeof(Node));//创建一个指针,要么初始化,要么制空
	if (headnode == NULL)
	{
		printf("创建头节点失败\n");
		exit(0);
	}
	headnode->next = NULL;
	return headnode;
}

Node* creatnode(int input)
{
	Node* node = (Node*)malloc(sizeof(Node));
	if (node == NULL)
	{
		printf("添加数据失败\n");
		exit(0);
	}
	node->data = input;
	node->next = NULL;
	return node;
}

void PrintNode(Node* headnode)
{
	Node* pMove = headnode->next;//定义一个辅助指针,用于遍历
	while (pMove)
	{
		printf("%d\n", pMove->data);
		pMove = pMove->next;
	}

}



void DelectNode(Node* headnode)
{
	int input = 0;
	scanf("%d", &input);
	Node* pMove = headnode;//定义一个辅助指针,用于遍历
	while (pMove->next != NULL && pMove->next->data != input)//这里不能调换顺序!
	{                                                        //要先判断pMove->next是否为NULL,
		pMove = pMove->next;                                 //再判断pMove->next->data,
	}                                                        //否则就读取了空指针的data,会报错!
                                                              
	if (pMove->next == NULL)
	{
		printf("该结点不存在\n");
		exit(0);
	}

	Node* d = pMove->next;
	pMove->next = pMove->next->next;
	free(d);
	printf("该结点已删除\n");
}

void FreeNode(Node* headnode)
{
	Node* pMove = headnode;
	Node* pfree = pMove;
	while (pMove != NULL)
	{
		pMove = pMove->next;
		free(pfree);
		pfree = pMove;

	}

	printf("链表已释放成功\n");
}
int main()
{
	int input = 0;
	Node* headnode = creathead();//创建头结点
	Node* p = headnode;//辅助指针
	
	for (int i = 0; i < 5; i++)//头部插入法
	{
		scanf("%d", &input);
		Node* node = creatnode(input);//创建结点
		node->next = p->next;
		p->next = node;
	}

	
	//endinsert(headnode);
	DelectNode(headnode);
	PrintNode(headnode);//遍历链表
	FreeNode(headnode);
	return 0;
}

7.翻转链表(无头)

Node* ReverseList(Node* headnode)//翻转无头链表
{
	Node* n1;//还未考虑链表小于3的情况
	Node* n2;
	Node* n3;
	n1 = NULL;
	n2 = headnode;
	n3 = headnode->next;
	while (n2 != NULL)//迭代
	{
		n2->next = n1;
		n1 = n2;
		n2 = n3;
		if (n3)
		{
			n3 = n3->next;
		}
		
	}
	printf("链表翻转成功\n");
	return n1;
}

8.双向链表

typedef struct Node
{
	int val;
	Node* pre;
	Node* next;
}Node;
Node* CreatList()
{
	Node* head = (Node*)malloc(sizeof(Node));
	head->val = NULL;
	head->pre = head;
	head->next = head;
	return head;
}
void ListPushBack(Node* head,int val)//尾插法
{
	Node* node = (Node*)malloc(sizeof(Node));
	Node* tail = head->pre;
	
	node->val = val;
	node->pre = tail;
	node->next = head;

	tail->next = node;
	head->pre = node;
	

}
void DelectNode(Node* head,int val)//尾删法
{
	Node* cur = head->next;
	while (cur != head)
	{
		if (cur->val == val)//指定数据的删除(还不够完善)
		{
			cur->pre->next = cur->next;
			cur->next->pre = cur->pre;
			cur->next = NULL;
			cur->pre = NULL;
			free(cur);
			printf("删除成功");
			break;
		}
		cur = cur->next;
	}
	if (cur == head)
	{
		printf("该结点不存在\n");
	}
	
}
void SearchNode(Node* head, int val)
{
	Node* cur = head->next;
	while (cur != head)
	{
		if (cur->val == val)//指定数据的删除(还不够完善)
		{
			printf("找到了,该结点存在\n");
			break;
		}
		cur = cur->next;
	}
	
	if (cur == head)
	{
		printf("该结点不存在\n");
	}
}

void ModifyNode(Node* head, int val)
{
	int input = 0;
	Node* cur = head->next;
	while (cur != head)
	{
		if (cur->val == val)//指定数据的删除(还不够完善)
		{
			printf("您要将数据%d修改为:\n",val);
			scanf("%d", &input);
			cur->val = input;
			printf("修改成功\n");
			break;
		}
		cur = cur->next;
	}

	if (cur == head)
	{
		printf("该结点不存在\n");
	}
}
void ListPrint(Node* head)
{
	Node* cur = head->next;
	while (cur->next != head)
	{
		printf("%d<->", cur->val);
		cur = cur->next;
	}
	printf("%d\n", cur->val);
	
}
int main()
{
	Node* head = CreatList();
	int i = 0;
	int val = 0;
	printf("请输入您要添加的数据:\n");
	for (i = 0; i < 5; i++)
	{
		scanf("%d", &val);
		ListPushBack(head, val);
		val = 0;
	}
	ListPrint(head);
	printf("请选择您要修改的数据:\n");
	scanf("%d", &val);
	ModifyNode(head, val);

	ListPrint(head);
	printf("请选择您要删除的数据:\n");
	scanf("%d", &val);
	DelectNode(head, val);

	ListPrint(head);
	printf("请选择您要查找的数据\n");
	scanf("%d", &val);
	SearchNode(head, val);
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值