基础数据结构———有头链表(小白学习笔记)

链表就是不连续的内存块通过指针联系起来成为一个数组(个人的理解)
结构体的两大块:数据块,指针块
我们可以通过结构体来实现链表
但是如何新建一个链表呢,我这里讲一个有头链表
头的话就是没有数据域只有指针,带向后面的节点,后面的节点再指向一个节点
在这里插入图片描述

我们可以用结构体先表现出来节点

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

创建有头链表:即分配头指针空间并把指针指向NULL:

struct node* creatlist() {
	struct node* headnode = (struct node*)malloc(sizeof(node));
	headnode->next = NULL;
	return headnode;
}

现在我们的链表创建好了,下一步就是实现链表的插入工作,插入之前必定要实现新的节点的创建:

//创建节点为插入做准备
struct node* newnode(int data) {
	struct node* newnode = (struct node*)malloc(sizeof(node));
	newnode->data = data;
	newnode->next = NULL;
	return newnode;
}

现在我们实现表头法插入:
先分析如何实现,我们画个图:在这里插入图片描述
原理知道了,我们代码实现

void insertbyhead(struct node* headnode,int data) {
	struct node* newNode = newnode(data);
	newNode->next = headnode->next;
	headnode->next = newNode;
}//要传入要插入的链表的头节点和要插入的数据

我们来看一下插入效果

//打印链表所存数据
void printlist(struct node* headnode) {
	struct node* pmove = headnode->next;//有表头链表,要从第二个开始
	if (pmove == NULL) printf("空链表\n");
	else {
		while (pmove != NULL) {
			printf("%d->", pmove->data);
			pmove = pmove->next;
		}
		printf("\n");
	}
}
int main() {
	struct node* list1 = creatlist();
	insertbyhead(list1, 1);
	insertbyhead(list1, 2);
	printlist(list1);
}

在这里插入图片描述
我们来看表尾法插入:
在这里插入图片描述
第一项完成的工作应该是找尾结点,然后再实现插入
看代码:

void insertbytail(struct node* headnode, int data) {
	struct node* newNode = newnode(data);
	struct node* tailnode = headnode;
	while (tailnode->next != NULL) 
	{ 
		tailnode = tailnode->next; 
	}
	tailnode->next = newNode;
}

看一下效果:

int main() {
	struct node* list1 = creatlist();
	insertbyhead(list1, 1);
	insertbyhead(list1, 2);
	printlist(list1);
	insertbytail(list1, -3);
	printlist(list1);
}

在这里插入图片描述
现实中我们应该是随处插入,那么我们来实现一下查找节点插入:
在这里插入图片描述

//插在某个数据的前面的函数
void insert(struct node* headnode, int data, int posdata) {
	struct node* posfrt = headnode;
	struct node* pos = headnode->next;
	while (pos != NULL&& pos->data != posdata) {
		posfrt = pos;
		pos = pos->next;
	}
	if (pos == NULL)printf("找不到合适位置\n");
	else {
		struct node* newNode = newnode(data);//找不到合适的位置时候就先别申请内存节省空间
		newNode->next = pos;
		posfrt->next = newNode;
	}
}

查看效果:

int main() {
	struct node* list1 = creatlist();
	insertbyhead(list1, 1);
	insertbyhead(list1, 2);
	printlist(list1);
	insertbytail(list1, -3);
	printlist(list1);
	insert(list1, 8, -3);
	printlist(list1);
}

在这里插入图片描述
插入实现了,该删除节点了:
表头法删除节点:
在这里插入图片描述
代码实现:

void deletebyhead(struct node* headnode) {
	if (headnode->next == NULL) printf("这是个空链表\n");
	else {
		struct node* nextnode = headnode->next;
		headnode->next = headnode->next->next;
		free(nextnode);
	}
}

表尾法删除和表头法删除一样删除节点,跟表尾法插入一样要找尾结点,不同的是,要查询是不是空链表防止bug
看代码:

void deletebytail(struct node* headnode) {
	if (headnode->next == NULL) printf("这是个空链表\n");//防止bug,查询一下是不是空链表
	else {
		struct node* tailnode = headnode->next;
		struct node* tailfro = headnode;
		while (tailnode->next!=NULL) {
			tailfro = tailnode;
			tailnode = tailnode->next;
		}
		tailfro->next = NULL;
		free(tailnode);
	}
}

查找并删除,跟查找插入一样,要先查找哦:
看图
在这里插入图片描述
代码实现如下:

void deletenode(struct node* headnode, int data) {
	struct node* deletenodefro = headnode;
	struct node* deletenode = headnode->next;
	while (deletenode != NULL && deletenode->data != data) {
		deletenodefro = deletenode;
		deletenode = deletenode->next;
	}
	if (deletenode == NULL)printf("找不到对应节点\n");
	else {
		deletenodefro->next = deletenode->next;
		free(deletenode);
	}
}

整体我们已经弄完了,整体的代码如下:

#include<stdio.h>
#include<stdlib.h>
struct node
{
	int data;
	struct node* next;
};
struct node* creatlist() {
	struct node* headnode = (struct node*)malloc(sizeof(node));
	headnode->next = NULL;
	return headnode;
}
struct node* newnode(int data) {
	struct node* newnode = (struct node*)malloc(sizeof(node));
	newnode->data = data;
	newnode->next = NULL;
	return newnode;
}
void insertbyhead(struct node* headnode,int data) {
	struct node* newNode = newnode(data);
	newNode->next = headnode->next;
	headnode->next = newNode;
}
void printlist(struct node* headnode) {
	struct node* pmove = headnode->next;//有表头链表,要从第二个开始
	if (pmove == NULL) printf("空链表\n");
	else {
		while (pmove != NULL) {
			printf("%d->", pmove->data);
			pmove = pmove->next;
		}
		printf("\n");
	}
}
void insertbytail(struct node* headnode, int data) {
	struct node* newNode = newnode(data);
	struct node* tailnode = headnode;
	while (tailnode->next != NULL) 
	{ 
		tailnode = tailnode->next; 
	}
	tailnode->next = newNode;
}
void insert(struct node* headnode, int data, int posdata) {
	struct node* posfrt = headnode;
	struct node* pos = headnode->next;
	while (pos != NULL&& pos->data != posdata) {
		posfrt = pos;
		pos = pos->next;
	}
	if (pos == NULL)printf("找不到合适位置\n");
	else {
		struct node* newNode = newnode(data);//找不到合适的位置时候就先别申请内存节省空间
		newNode->next = pos;
		posfrt->next = newNode;
	}
}
void deletebyhead(struct node* headnode) {
	if (headnode->next == NULL) printf("这是个空链表\n");
	else {
		struct node* nextnode = headnode->next;
		headnode->next = headnode->next->next;
		free(nextnode);
	}
}
void deletebytail(struct node* headnode) {
	if (headnode->next == NULL) printf("这是个空链表\n");//防止bug,查询一下是不是空链表
	else {
		struct node* tailnode = headnode->next;
		struct node* tailfro = headnode;
		while (tailnode->next!=NULL) {
			tailfro = tailnode;
			tailnode = tailnode->next;
		}
		tailfro->next = NULL;
		free(tailnode);
	}
}
void deletenode(struct node* headnode, int data) {
	struct node* deletenodefro = headnode;
	struct node* deletenode = headnode->next;
	while (deletenode != NULL && deletenode->data != data) {
		deletenodefro = deletenode;
		deletenode = deletenode->next;
	}
	if (deletenode == NULL)printf("找不到对应节点\n");
	else {
		deletenodefro->next = deletenode->next;
		free(deletenode);
	}
}
int main() {
	struct node* list1 = creatlist();
	insertbyhead(list1, 1);
	insertbyhead(list1, 2);
	printlist(list1);
	insertbytail(list1, -3);
	printlist(list1);
	insert(list1, 8, -3);
	printlist(list1);
	deletebyhead(list1);
	printlist(list1);
	deletebytail(list1);
	printlist(list1);
	deletenode(list1, -1);
	printlist(list1);
	deletenode(list1, 8);
	printlist(list1);
	deletenode(list1, 1);
	printlist(list1);
}

有头链表实现完成了!!!

  • 3
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值