0
点赞
收藏
分享

微信扫一扫

【网络安全】零日漏洞(0day)是什么?如何防范零日攻击?

文章目录


1 双向链表的结构

在这里插入图片描述

2 双向链表的实现

2.1 定义双向链表的数据结构

typedef int ListDataType;

typedef struct ListNode
{
	ListDataType data;		//整型数据
	struct ListNode* next;	//前驱指针
	struct ListNode* pre;	//后驱指针

}ListNode;

2.2 打印链表

void ListPrint(ListNode* phead)
{
	ListNode* cur = phead->next;	//头结点,哨兵位的下一位
	while (cur != phead)//双向循环链表,循环到哨兵位为止
	{
		printf("%d-> ", cur->data);
		cur = cur->next;
	}
}

在这里插入图片描述

2.3 初始化链表

ListNode* ListInit()
{
	ListNode* phead = (ListNode*)malloc(sizeof(ListNode));
	if (phead == NULL)
	{
		perror("malloc error");
		return;
	}
	phead->data = -1;
	phead->next = phead->pre = phead;
	return phead;
}

在这里插入图片描述

2.4 销毁链表

void ListDestory(ListNode* phead)
{
	assert(phead);
	ListNode* cur = phead->next;	//头结点,哨兵位的下一位
	while (cur!=phead)
	{
		//释放cur前,记录下cur->next,释放cur后,把cur->next赋值给cur
		ListNode* NEXT = cur->next;
		free(cur);
		cur = NEXT;
	}
	//释放哨兵位
	free(phead);
	phead = NULL;
}

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

2.5 尾插,头插

//插入数据前创建内存空间
ListNode* ListBuyNode(ListDataType x)
{
	ListNode* node = (ListNode*)malloc(sizeof(ListNode));
	node->data = x;
	node->next = node->pre = NULL;

	return node;
}

void ListPushBack(ListNode* phead, ListDataType x)
{
	assert(phead);
	ListNode* node = ListBuyNode(x);

	//先处理新节点前驱指针和后驱指针
	node->pre = phead->pre;
	node->next = phead;
	//再处理原链表最后一个节点和phead
	phead->pre->next = node;
	phead->pre = node;
}

void ListPushFront(ListNode* phead, ListDataType x)
{
	assert(phead);
	ListNode* node = ListBuyNode(x);
	//先处理新节点前驱指针和后驱指针
	node->pre = phead;
	node->next = phead->next;
	//再处理phead和原链表第一个节点(phead->next)
	phead->next->pre = node;
	phead->next = node;

}

2.6 尾删,头删

在这里插入图片描述

void ListPopBack(ListNode* phead)
{
	assert(phead);
	//链表不能只有一个哨兵位
	assert(phead->next != phead);
	ListNode* del = phead->pre;
	//删除节点的前驱指针
	del->pre->next = phead;
	//phead的前驱指针
	phead->pre = del->pre;
}

void ListPopFront(ListNode* phead)
{
	assert(phead && phead->next != phead);
	ListNode* del = phead->next;

	del->next->pre = phead;
	phead->next = del->next;

	free(del);
	del = NULL;

}

在这里插入图片描述

在这里插入图片描述

2.7 根据头次出现数据找下标

ListNode* ListFind(ListNode* phead, ListDataType x)
{
	assert(phead);
	ListNode* cur = phead->next;
	while (cur != phead)
	{
		if (cur->data == x)
		{
			return cur;
		}
		cur = cur->next;
	}

	return NULL;
}

在这里插入图片描述

在这里插入图片描述

2.8 定点前插入

在这里插入图片描述

void ListInsert(ListNode* pos, ListDataType x)
{
	assert(pos);
	ListNode* node= ListBuyNode(x);
	//先处理node
	node->next = pos;
	node->pre = pos->pre;
	//在处理pos->pre和pos
	pos->pre->next= node;
	node->next->pre = node;

}

在这里插入图片描述

2.9 删除pos位置

在这里插入图片描述

void ListErase(ListNode* pos)
{
	assert(pos);
	pos->next->pre = pos->pre;
	pos->pre->next = pos->next;
	free(pos);
	pos = NULL;
}

在这里插入图片描述
在这里插入图片描述

2.10 定点后插入

在这里插入图片描述

void ListInsertAfter(ListNode* pos, ListDataType x)
{
	assert(pos);
	ListNode* node = ListBuyNode(x);
	//node的prev 和 next
	node->next = pos->next;
	node->pre = pos;

	//pos的next 和 pos->next的prev
	pos->next = node;
	node->next->pre = node;
}

在这里插入图片描述

3 完整代码

3.1 List.h

#define _CRT_SECURE_NO_WARNINGS
#include<stdbool.h>
#include<stddef.h>
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>

//0 定义双向循环链表节点结构
typedef int ListDataType;

typedef struct ListNode
{
	ListDataType data;
	struct ListNode* next;	//前驱指针
	struct ListNode* pre;	//后驱指针

}ListNode;

//0 打印链表
void ListPrint(ListNode* phead);

//1 初始化链表
ListNode* ListInit();

//2 销毁链表
void ListDestory(ListNode* phead);

//3 尾插,头插
void ListPushBack(ListNode* phead, ListDataType x);
void ListPushFront(ListNode* phead, ListDataType x);

//4 尾删,头删
void ListPopBack(ListNode* phead);
void ListPopFront(ListNode* phead);

//5 根据数找到第一次出现的下标
ListNode* ListFind(ListNode* phead, ListDataType x);
  
//6 定点前插入
void ListInsert(ListNode* pos, ListDataType x);

//7 删除pos位置
void ListErase(ListNode* pos);

//8 定点后插入
void ListInsertAfter(ListNode* pos, ListDataType x);



3.2 Lish.c

#include "List.h"

void ListPrint(ListNode* phead)
{
	ListNode* cur = phead->next;
	while (cur != phead)//双向循环链表,循环到哨兵位为止
	{
		printf("%d-> ", cur->data);
		cur = cur->next;
	}
}

ListNode* ListInit()
{
	ListNode* phead = (ListNode*)malloc(sizeof(ListNode));
	if (phead == NULL)
	{
		perror("malloc error");
		return;
	}
	phead->data = -1;
	phead->next = phead->pre = phead;
	return phead;
}

void ListDestory(ListNode* phead)
{
	assert(phead);
	ListNode* cur = phead->next;	//头结点,哨兵位的下一位
	while (cur!=phead)
	{
		//释放cur前提前记录下cur->next,释放cur后,把cur->next赋值给cur
		ListNode* NEXT = cur->next;
		free(cur);
		cur = NEXT;
	}
	//释放哨兵位
	free(phead);
	phead = NULL;
}

//插入数据前创建内存空间
ListNode* ListBuyNode(ListDataType x)
{
	ListNode* node = (ListNode*)malloc(sizeof(ListNode));
	node->data = x;
	node->next = node->pre = NULL;

	return node;
}

void ListPushBack(ListNode* phead, ListDataType x)
{
	assert(phead);
	ListNode* node = ListBuyNode(x);

	//先处理新节点前驱指针和后驱指针
	node->pre = phead->pre;
	node->next = phead;
	//再处理原链表最后一个节点和phead
	phead->pre->next = node;
	phead->pre = node;
}

void ListPushFront(ListNode* phead, ListDataType x)
{
	assert(phead);
	ListNode* node = ListBuyNode(x);
	//先处理新节点前驱指针和后驱指针
	node->pre = phead;
	node->next = phead->next;
	//再处理phead和原链表第一个节点(phead->next)
	phead->next->pre = node;
	phead->next = node;

}

void ListPopBack(ListNode* phead)
{
	assert(phead);
	//链表不能只有一个哨兵位
	assert(phead->next != phead);
	ListNode* del = phead->pre;
	//删除节点的前驱指针
	del->pre->next = phead;
	//phead的前驱指针
	phead->pre = del->pre;
}

void ListPopFront(ListNode* phead)
{
	assert(phead && phead->next != phead);
	ListNode* del = phead->next;

	del->next->pre = phead;
	phead->next = del->next;

	free(del);
	del = NULL;

}

ListNode* ListFind(ListNode* phead, ListDataType x)
{
	assert(phead);
	ListNode* cur = phead->next;
	while (cur != phead)
	{
		if (cur->data == x)
		{
			return cur;
		}
		cur = cur->next;
	}

	return NULL;
}

void ListInsert(ListNode* pos, ListDataType x)
{
	assert(pos);
	ListNode* node= ListBuyNode(x);
	//先处理node
	node->next = pos;
	node->pre = pos->pre;
	//在处理pos->pre和pos
	pos->pre->next= node;
	node->next->pre = node;

}

void ListErase(ListNode* pos)
{
	assert(pos);
	pos->next->pre = pos->pre;
	pos->pre->next = pos->next;
	free(pos);
	pos = NULL;
}

void ListInsertAfter(ListNode* pos, ListDataType x)
{
	assert(pos);
	ListNode* node = ListBuyNode(x);
	//node的prev 和 next
	node->next = pos->next;
	node->pre = pos;

	//pos的next 和 pos->next的prev
	pos->next = node;
	node->next->pre = node;
}


3.3 test.c

#include"List.h"

void test1()
{
	ListNode* plist = ListInit();
}

void test2()
{
	ListNode* plist = ListInit();;
	ListPushBack(plist, 1);
	ListPushBack(plist, 4);
	ListPushBack(plist, 7);

	ListPrint(plist);  //1->4->7->
	ListDestory(plist);
}

void test3()
{
	ListNode* plist = ListInit();;
	ListPushFront(plist, 1);
	ListPushFront(plist, 4);
	ListPushFront(plist, 7);

	ListPrint(plist);//7->4->1->
	ListDestory(plist);
}

void test4()
{
	ListNode* plist = ListInit();;
	ListPushBack(plist, 1);
	ListPushBack(plist, 2);
	ListPushBack(plist, 3);
	ListPushBack(plist, 4);
	ListPushBack(plist, 5);
	ListPushBack(plist, 6);
	ListPushBack(plist, 7);
	ListPushBack(plist, 8);
	ListPushBack(plist, 9);
	ListPrint(plist);
	printf("\n");

	ListPopBack(plist);
	ListPopBack(plist);
	ListPopFront(plist);
	ListPopFront(plist);

	ListPrint(plist);
	ListDestory(plist);
}

void test5()
{
	ListNode* plist = ListInit();;
	ListPushBack(plist, 1);
	ListPushBack(plist, 2);
	ListPushBack(plist, 3);
	ListPushBack(plist, 4);
	ListPushBack(plist, 5);
	ListPrint(plist);
	printf("\n");

	//测试指定位置
	ListNode* Find1 = ListFind(plist, 2);
	ListNode* Find2 = ListFind(plist, 4);
	ListInsert(Find1, 10);
	ListInsertAfter(Find2, 20);
	ListPrint(plist);
	printf("\n");

	ListErase(Find1);
	ListPrint(plist);
	ListDestory(plist);
}

int main()
{
	//test1();
	//test2();
	//test3();
	//test4();
	test5();


	return 0;
}
举报

相关推荐

0 条评论