0
点赞
收藏
分享

微信扫一扫

高阶JavaScript用法

Sikj_6590 2023-04-23 阅读 57

目录

1.链表的概念及结构 

2.链表的实现 

2.1链表的创建 

2.2结点的创建 

2.3从头部插入数据 

2.4链表的打印 

2.5从尾部插入数据 

 2.6从尾部删除数据

2.7从头部删除数据

2.8在链表中查找数据

2.9修改链表中的数据

2.10在单链表中的pos之前插入数据 

2.11在单链表中的pos之后插入数据

2.12在单链表中的pos之前删除数据 

 2.13在单链表中的pos之后删除数据 

3.完整代码


1.链表的概念及结构 

2.链表的实现 

2.1链表的创建 

2.2结点的创建 

2.3从头部插入数据 

2.4链表的打印 

2.5从尾部插入数据 

 2.6从尾部删除数据

2.7从头部删除数据

2.8在链表中查找数据

2.9修改链表中的数据

2.10在单链表中的pos之前插入数据 

2.11在单链表中的pos之后插入数据

2.12在单链表中的pos之前删除数据 

 2.13在单链表中的pos之后删除数据 

3.完整代码

头文件:SList.h

#pragma once

// 头文件的包含
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>

//链表的创建
typedef int SLTDataType;

typedef struct SLTNode
{
	SLTDataType data;
	struct SLTNode* next;
}SLTNode;


//函数的声明
//打印链表
void SLPrint(SLTNode* phead);

//创建节点
SLTNode* BuySLTNode(SLTDataType x);

//头插
void SLPushFront(SLTNode** pphead, SLTDataType x);

//尾插
void SLPushBack(SLTNode** pphead, SLTDataType x);

//尾删
void SLPopBack(SLTNode** pphead);

//头删
void SLPopFront(SLTNode** pphead);

//查找
SLTNode* SLFindNode(SLTNode* phead, SLTDataType x);

//单链表在pos之前插入数据
void SLInsert(SLTNode** pphead, SLTNode* pos, SLTDataType x);

// 单链表在pos位置之后插入x
void SLInsertAfter(SLTNode* pos, SLTDataType x);

// 单链表在pos位置之前删除
void SLErase(SLTNode** pphead, SLTNode* pos);

// 单链表在pos位置之后删除
void SLEraseAfter(SLTNode* pos);

 源文件:SList.c

#define _CRT_SECURE_NO_WARNINGS 1

#include "SList.h"

//打印
void SLPrint(SLTNode* phead)
{
	SLTNode* cur = phead;   
	while (cur)   //判断是否为NULL
	{
		printf("%d->", cur->data);
		cur = cur->next;  //指向下一个结点
	}
	printf("NULL\n");
}


//创建节点
SLTNode* BuySLTNode(SLTDataType x)
{
	SLTNode* newnode = (SLTNode*)malloc(sizeof(SLTNode));
	if (newnode == NULL)
	{
		perror("malloc fail");
		return NULL;
	}
	newnode->data = x;
	newnode->next = NULL;

	return newnode;
}

//头插
void SLPushFront(SLTNode** pphead, SLTDataType x)
{
	assert(pphead);                     //防止传参错误导致空指针
	SLTNode* newnode = BuySLTNode(x);   //创建要插入的结点
	newnode->next = *pphead;            //改变新节点的下一个指向
	*pphead = newnode;                  //改变头指针的指向
}

//尾插
void SLPushBack(SLTNode** pphead, SLTDataType x)
{
	assert(pphead);
	SLTNode* newnode = BuySLTNode(x);  //创建结点
	if (*pphead == NULL)   //判断链表是否为空
	{
		*pphead = newnode;  //若为空直接进行插入
	}
	else
	{
		SLTNode* tail = *pphead;  //找尾结点
		while (tail->next)
		{
			tail = tail->next;
		}
		tail->next = newnode;  //改变尾结点的指向
	}
}


//尾删
方法一:记录尾节点的上一个节点
//void SLPopBack(SLTNode** pphead)
//{
//	//为空
//  assert(pphead);
//	assert(*pphead);
//	//只有一个节点
//	if ((*pphead)->next == NULL)
//	{
//		free(*pphead);
//		*pphead = NULL;
//	}
//	else
//	{
//		SLTNode* tail = *pphead;
//		SLTNode* Prev = *pphead;
//		while (tail->next)
//		{
//			Prev = tail;
//			tail = tail->next;
//		}
//		free(Prev->next);
//		Prev->next = NULL;
//	}
//}

//方法二:直接通过next指向的next来释放
void SLPopBack(SLTNode** pphead)
{
	//为空
	assert(*pphead);
	assert(pphead);

	//只有一个节点
	if ((*pphead)->next == NULL)
	{
		free(*pphead);
		*pphead = NULL;
	}
	else
	{
		SLTNode* tail = *pphead;
		while (tail->next->next)
		{
			tail = tail->next;
		}
		free(tail->next);
		tail->next = NULL;	
	}
}

//头删
void SLPopFront(SLTNode** pphead)
{
	//为空
	assert(*pphead);
	assert(pphead);

	只有一个节点
	//if ((*pphead)->next == NULL)
	//{
	//	free(*pphead);
	//	*pphead = NULL;
	//}
	//else
	//{
	//	SLTNode* Del = *pphead;
	//	*pphead = (*pphead)->next;
	//	free(Del);
	//	Del = NULL;
	//}

	//优化
	SLTNode* Del = *pphead;
	*pphead = (*pphead)->next;
	free(Del);
	Del = NULL;

}


//查找
SLTNode* SLFindNode(SLTNode* phead, SLTDataType x)
{
	SLTNode* cur = phead;
	while (cur)
	{
		if (cur->data == x)
		{
			return cur;
		}
		cur = cur->next;
	}
	return NULL;
}

//单链表在pos之前插入数据
void SLInsert(SLTNode** pphead, SLTNode* pos, SLTDataType x)
{
	assert(pos);
	assert(pphead);

	SLTNode* prev = *pphead;  //记录前一个结点
	SLTNode* newnode = BuySLTNode(x);  //创建结点
	//如果pos就在头指针的位置,那么就是进行头插的过程
	if (*pphead == pos)
	{
		SLPushFront(pphead, x);
	}
	else
	{
		while (prev->next != pos)  //找到前一个结点
		{
			prev = prev->next;   
		}
		prev->next = newnode;  //改变指向
		newnode->next = pos;
	}
}

//在pos后面的位置插入数据
void SLInsertAfter(SLTNode* pos, SLTDataType x)
{
	assert(pos);
	SLTNode* newnode = BuySLTNode(x);
	newnode->next = pos->next;
	pos->next = newnode;
}

// 单链表在pos位置之前删除
void SLErase(SLTNode** pphead, SLTNode* pos)
{
	assert(pos);
	assert(pphead);
	if (pos == *pphead)
	{
		SLPopFront(pphead);
	}
	else
	{
		SLTNode* prev = *pphead;  //记录前一个结点
		while (prev->next != pos)  //找到前一个结点
		{
			prev = prev->next;
		}

		prev->next = pos->next;
		free(pos);
		pos = NULL;
	}
}


// 单链表在pos位置之后删除
void SLEraseAfter(SLTNode* pos)
{
	assert(pos);
	if (pos->next)
	{
		SLTNode* next = pos->next;
		SLTNode* nextnext = next->next;
		pos->next = nextnext;
		free(next);
		next = NULL;
	}
}

源文件:Test.c

#define _CRT_SECURE_NO_WARNINGS 1


//数据结构: 单链表

#include "SList.h"

void TestSLTNode1()
{
	SLTNode* plist = NULL;

	//头插
	SLPushFront(&plist, 1);
	SLPushFront(&plist, 2);
	SLPrint(plist);

	//尾插
	SLPushBack(&plist, 0);
	SLPushBack(&plist, -1);
	SLPrint(plist);

	//头删
	SLPopFront(&plist);
	SLPrint(plist);

	//尾删
	SLPopBack(&plist);
	SLPrint(plist);

	//查找
	SLTNode* mark = SLFindNode(plist, 1);

	//修改
	if (mark != NULL)  //判断是否找到了
	{
		mark->data = 10;
	}
	SLPrint(plist);

	//在pos1之前插入数据
	SLTNode* pos1 = SLFindNode(plist, 10);
	if (pos1 != NULL)
	{
		SLInsert(&plist, pos1, 100);
	}
	SLPrint(plist);


	//在pos2之后插入数据
	SLTNode* pos2 = SLFindNode(plist, 10);
	if (pos2 != NULL)
	{
		SLInsertAfter(pos2, 100);
	}
	SLPrint(plist);


	//删除pos3之前的数据
	SLTNode* pos3 = SLFindNode(plist, 10);
	if (pos3 != NULL)
	{
		SLErase(&plist, pos3);
	}
	SLPrint(plist);


	//删除pos4之后的数据
	SLTNode* pos4 = SLFindNode(plist, 10);
	if (pos4 != NULL)
	{
		SLEraseAfter(pos4);
	}
	SLPrint(plist);

}

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

举报

相关推荐

0 条评论