10.链表及链表面试题

学习自黑马程序员视频.

链表

  • 作者介绍
  • 1.链表的基本概念
  • 2.链表的建立
    • 2.1 静态链表
    • 2.2 动态链表
  • 链表面试题(待做)

作者介绍

张伟伟,男,西安工程大学电子信息学院,2019级硕士研究生,张宏伟人工智能课题组。
微信公众号:可随时查阅,搜索—张二牛的笔记,内容会分类上传。
研究方向:机器视觉与人工智能。
电子邮件:[email protected]

  • 课题组CSDN官方账号,欢迎一键三连: https://blog.csdn.net/m0_37758063/article/details/113527955?spm=1001.2014.3001.5501.

1.链表的基本概念

链表(Linked list)是一种常见的基础数据结构:(简要记忆)
是一种线性表非顺序存储有指针域和数据域,并不像数组那样将存储在一个连续的内存地址空间里,链表的开销主要是访问顺序性和组织链的空间损失====。

  • 数组和链表的区别
    数组:一次性分配所需的连续的存储空间,随机访问元素效率高。但是删除和插入效率低。
    链表:无需一次性分配连续的存储数据,先建立节点,再指针建立关系。不需要连续的存储空间,删除和插入某个元素效率高,随机访问元素效率低。

  • 链表的分类:

    链表按照存储方式分为静态链表(结构体,取地址)和动态链表(指针 开辟内存,指针赋值)。
    链表有带头结点和不带头节点的链表
    单向链表和双向链表,循环链表(待补充---------


2.链表的建立

2.1 静态链表

静态链表是指链表节点开辟在栈区,静态链表的建立和遍历。其C语言描述如下:

/* 静态链表的建立和遍历 */
#define _CRT_SECURE_NO_WARNINGS
#include
#include
#include

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

void test01();
int main()
{
	
	test01();
	return 0;
}

void test01()
{
	//建立节点
	struct LinkNode node1  = {30,NULL};
	struct LinkNode node2  = {20,NULL};
	struct LinkNode node3  = {30,NULL};
	struct LinkNode node4  = {40,NULL};
	struct LinkNode node5  = {50,NULL};
	//建立关系
	node1.next  =  &node2;
	node2.next  =  &node3;
	node3.next  =  &node4;
	node4.next  =  &node5;
	//遍历
	//1.定义辅助指针
	struct LinkNode *pCurrent  =  &node1;
	while(pCurrent != NULL)
	{
		printf("%d ",pCurrent->data);
		pCurrent = pCurrent->next;
	}
}

2.2 动态链表

链表的遍历
链表的插入
链表的删除
链表的清空
链表的销毁

/* 静态链表的建立和遍历 */
#define _CRT_SECURE_NO_WARNINGS
#include
#include
#include

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

void test01();
void free_malloc(struct LinkNode * p);
int main()
{
	
	test01();
	return 0;
}

void test01()
{
	//建立节点
	struct LinkNode *node1  = malloc(sizeof(struct LinkNode));
	struct LinkNode *node2  = malloc(sizeof(struct LinkNode));
	struct LinkNode *node3  = malloc(sizeof(struct LinkNode));
	struct LinkNode *node4  = malloc(sizeof(struct LinkNode));
	struct LinkNode *node5  = malloc(sizeof(struct LinkNode));
	node1->data  = 10;
	node2->data  = 20;
	node3->data  = 30;
	node4->data  = 40;
	//建立关系
	node1->next  = node2;
	node2->next  = node3;
	node3->next  = node4;
	node4->next  = NULL;
	
	//遍历
	//1.定义辅助指针
	struct LinkNode *pCurrent  =  node1;
	while(pCurrent != NULL)
	{
		printf("%d ",pCurrent->data);
		pCurrent = pCurrent->next;
	}
	//判断空后再释放,自定义函数实现内存手动释放
	free_malloc(node1);
	// free(node1);
	free(node2);
	free(node3);
	free(node4);
}
void free_malloc(struct LinkNode * p)
{
	if(p != NULL)
	{
		free(p);
		p = NULL;
	}
}
  • 分文件编程,定义函数
#define _CRT_SECURE_NO_WARNINGS
#include
#include
#include
struct LinkNode
{
	int num;
	struct LinkNode * next;
};

//初始化链表
struct LinkNode * initLinkList();

//遍历链表
void foreach_LinkList(struct LinkNode * pHeader);

//插入链表
void insert_LinkList(struct LinkNode * pHeader, int oldVal, int newVal);

//删除链表
void delete_LinkList(struct LinkNode * pHeader, int val);

//清空链表
void clear_LinkList(struct LinkNode * pHeader);

//销毁链表
void destroy_LinkList(struct LinkNode * pHeader);

void test01()
{
	//初始化链表
	struct LinkNode * pHeader = initLinkList();

	//遍历链表
	printf("遍历链表结果为:\n");
	foreach_LinkList(pHeader);

	//插入链表
	// 10 1000  2000 20 3000 30  500
	insert_LinkList(pHeader, 20, 1000);
	// insert_LinkList(pHeader, 20, 2000);
	// insert_LinkList(pHeader, -1, 500);
	// insert_LinkList(pHeader, 30, 3000);
	printf("插入链表后,遍历----------链表结果为:\n");
	foreach_LinkList(pHeader);


	//删除链表
	// 10  20  30  500
	delete_LinkList(pHeader, 20);
	// delete_LinkList(pHeader, 3000);
	// delete_LinkList(pHeader, 1000);
	// delete_LinkList(pHeader, -1);
	printf("删除链表后,遍历链表结果为:\n");
	foreach_LinkList(pHeader);

	// //清空链表
	// clear_LinkList(pHeader);
	// printf("清空链表后,遍历链表结果为:\n");
	// insert_LinkList(pHeader, 111, 111);
	// insert_LinkList(pHeader, 222, 222);
	// insert_LinkList(pHeader, 333, 333);
	// foreach_LinkList(pHeader);

	// //销毁链表
	// destroy_LinkList(pHeader);
	// pHeader = NULL;
		
}

int main(){

	test01();

	//printf("%d\n", test01);

	system("pause");
	return EXIT_SUCCESS;
}

//初始化链表
struct LinkNode * initLinkList()
{
	//创建头节点
	struct LinkNode * pHeader = malloc(sizeof(struct LinkNode));

	if (pHeader == NULL)
	{
		return NULL;
	}

	//初始化头节点
	//pHeader->num = -1;  //头节点 不维护数据域
	pHeader->next = NULL;

	//记录尾节点位置,方便插入新的数据
	struct LinkNode * pTail = pHeader;
	int val = -1;
	while (1)
	{
		//让用户初始化几个节点,如果用户输入的是-1,代表插入结束
		printf("请初始化链表,如果输入-1代表结束\n");
		scanf("%d", &val);

		if (val == -1)
		{
			break;
		}

		//如果输入不是-1  插入节点到链表中
		 struct LinkNode * newNode = malloc(sizeof(struct LinkNode));
		 newNode->num = val;
		 newNode->next = NULL;

		 //更改指针的指向
		 pTail->next = newNode;
		 //更新新的尾节点的指向
		 pTail = newNode;

	}


	return pHeader;
}

//遍历链表
void foreach_LinkList(struct LinkNode * pHeader)
{
	if (pHeader == NULL)
	{
		return;
	}

	struct LinkNode * pCurrent = pHeader->next; //指定第一个有真实数据的节点

	while (pCurrent!=NULL)
	{
		printf("%d\n", pCurrent->num);
		pCurrent = pCurrent->next;
	}

}

//插入链表
void insert_LinkList(struct LinkNode * pHeader, int oldVal, int newVal)
{
	if (pHeader == NULL)
	{
		return;
	}

	//创建两个临时的节点
	struct LinkNode * pPrve = pHeader;
	struct LinkNode * pCurrent = pHeader->next;

	while (pCurrent != NULL)
	{
		if (pCurrent->num == oldVal)
		{
			break;
		}
		//如果没找到对应的位置,辅助指针向后移动
		pPrve = pCurrent;
		pCurrent = pCurrent->next;
	}

	//创建新节点
	struct LinkNode * newNode = malloc(sizeof(struct LinkNode));
	newNode->num = newVal;
	newNode->next = NULL;


	//建立关系
	newNode->next = pCurrent->next;
	pCurrent->next = newNode;


}


//删除链表
void delete_LinkList(struct LinkNode * pHeader, int val)
{
	struct LinkNode *pPrev = pHeader;
	struct LinkNode *pCurrent = pPrev->next;
	
	while(pCurrent !=  NULL)
	{
		
		if(pCurrent->num == val)
		{
			break;
		}
		printf("while");
		pPrev = pCurrent;
		pCurrent = pPrev->next;
		
	}
	if(pCurrent == NULL)
	{
		return;
	}

	pPrev->next  = pCurrent->next;
	
	free(pCurrent);

	pCurrent = NULL;
}




//清空链表
void clear_LinkList(struct LinkNode * pHeader)
{
	if (pHeader == NULL)
	{
		return;
	}

	struct LinkNode * pCurrent = pHeader->next;

	while (pCurrent != NULL)
	{
		//先保存住下一个节点的位置
		struct LinkNode * nextNode = pCurrent->next;

		free(pCurrent);

		pCurrent = nextNode;
	}

	pHeader->next = NULL;

}

//销毁链表
void destroy_LinkList(struct LinkNode * pHeader)
{

	if (pHeader == NULL)
	{
		return;
	}

	//先清空链表
	clear_LinkList(pHeader);

	//再释放头节点

	free(pHeader);
	pHeader = NULL;

}

链表面试题(待做)

链表面试题.

在这里插入代码片

你可能感兴趣的:(C语言基础学习,链表,数据结构)