链表就是不连续的内存块通过指针联系起来成为一个数组(个人的理解)
结构体的两大块:数据块,指针块
我们可以通过结构体来实现链表
但是如何新建一个链表呢,我这里讲一个有头链表
头的话就是没有数据域只有指针,带向后面的节点,后面的节点再指向一个节点
我们可以用结构体先表现出来节点
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);
}
有头链表实现完成了!!!