文章目录
前言
链表是一种重要的数据结构,用于存储和组织数据。它是由一系列节点组成的数据结构,每个节点包含一个数据元素和一个指向下一个节点的指针。链表相比于数组具有更灵活的插入和删除操作,但访问元素的效率较低。在本文中,我们将学习如何使用C语言实现链表,包括创建节点、插入数据、删除数据等操作。通过学习链表的实现和应用,我们可以更好地理解数据结构的设计和算法的应用。
一、链表基本概念
1、声明节点结构
typedef struct node
{
int data;//数据域
struct node * next;//下一个节点
} Node, *P_NODE;
2、创建节点变量
n1、n2、n3、n4、n5都存储在栈区。
使用malloc在内存中申请空间,存储在堆区。
Node n1 = { 5,NULL };
Node n2 = { 10,NULL };
Node n3 = { 9,NULL };
Node n4 = { 3,NULL };
Node n5 = { 8,NULL };*/
Node *p1 = malloc(sizeof(struct node));
p1->next = NULL;
p1->data = 5;
Node* p2 = malloc(sizeof(struct node));
p2->next = NULL;
p2->data = 10;
Node* p3 = malloc(sizeof(struct node));
p3->next = NULL;
p3->data = 9;
Node* p4 = malloc(sizeof(struct node));
p4->next = NULL;
p4->data = 3;
Node* p5 = malloc(sizeof(struct node));
p5->next = NULL;
p5->data = 8;
3、链表所有节点
将链表通过next的指向连接起来。
n1.next = &n2;
n2.next = &n3;
n3.next = &n4;
n4.next = &n5;
p1->next = p2;
p2->next = p3;
p3->next = p4;
p4->next = p5;
4、遍历链表
#include <stdio.h>
#include <malloc.h>
int main()
{
//Node* p = &n1;
Node* p = p1;
while (p)
{
printf("%d\n",p->data);
p = p->next;
}
return 0;
}
二、add添加
声明了头结点和尾节点指向了空,定义了一个创建节点的函数和往尾部添加节点的函数。
#include<stdio.h>
#include <stdlib.h>
#include"link.h"
PNode header = NULL;
PNode ender = NULL;
int main()
{
PNode p = create(5);
add(p);
add(create(10));
add(create(9));
add(create(3));
add(create(8));
return 0;
}
PNode create(int data)
{
Node* newNode = malloc(sizeof(struct node));
newNode->data = data;
newNode->next = NULL;
return newNode;
}
void add(PNode node)
{
if (header==NULL)
{
header = ender = node;
}
else
{
ender->next = node;
ender = node;
}
}
三、insert插入
该实例的插入实现的是中间插入。
代码主要实现了一个链表的创建、节点添加以及在指定位置之后插入新节点的功能。具体步骤为:先创建一个链表,向链表中添加若干节点,然后在指定索引位置的节点之后插入一个新节点。
代码详细解释
#include<stdio.h>
#include <stdlib.h>
#include"link.h"
int main ()
{
//测试用例
PNode p = create(5);
add(p);
add(create(10));
add(create(9));
add(create(3));
add(create(9));
insert_behind(2,create(666));
return 0;
}
/*中间插入*/
void insert_behind(int index, PNode node)
{
PNode p = header;
for (int i=0;i<index;i++)
{
p = p->next;
}
PNode q = p->next;
node->next = q;
p->next = node;
}
四、remove删除
主要实现了一个链表的操作,包括创建链表节点、向链表中添加节点、根据索引删除节点以及根据节点数据删除节点等功能。
代码的主要目的是构建一个链表,并对链表进行节点的添加和删除操作。具体来说,它创建了一个包含多个节点的链表,然后根据节点的数据值删除链表中所有值为 9 的节点。
#include<stdio.h>
#include <stdlib.h>
#include"link.h"
int main04()
{
PNode p = create(5);
add(p);
add(create(10));
add(create(9));
add(create(3));
add(create(9));
//remove_index(2);
remove_data(9);
return 0;
}
void remove_index(int index)
{
PNode p = header;
PNode q = NULL;
for (int i=0;i<index;i++)
{
q = p;
p = p->next;
}
PNode m=p->next;
q->next = m;
free(p);
p = NULL;
}
void remove_data(int data)
{
/*PNode p = header;
PNode q = NULL;
while (p->data!=data)
{
q = p;
p = p->next;
}
PNode m = p->next;
q->next = m;
free(p);
p = NULL;*/
int xb = indexOf(data);
if (xb>=0)
{
remove_index(xb);
}
}
五、查找
代码实现了一个简单链表的基本操作,包括创建节点、添加节点、删除节点、获取链表长度、根据索引获取节点、查找特定值节点的索引等功能。
#include<stdio.h>
#include"link.h"
#include <stdlib.h>
int main()
{
PNode p = create(5);
add(p);
add(create(10));
add(create(9));
add(create(3));
add(create(99));
add(create(999));
add(create(9999));
remove_data(99);
int len = size();
for (int i=0;i<len;i++)
{
PNode p = get(i);
printf("%d\n",p->data);
}
printf("999:%d\n", indexOf(999));
printf("666:%d\n", indexOf(666));
return 0;
}
int size()
{
int count = 0;
PNode p = header;
while (p)
{
count++;
p = p->next;
}
return count;
}
PNode get(int index)
{
PNode p = header;
for (int i = 0; i < index; i++)
{
p = p->next;
}
return p;
}
int indexOf(int data)
{
PNode p = header;
for (int i=0;p!=NULL;i++)
{
if (p->data == data)
{
return i;
}
p = p->next;
}
return -1;
}
总结
链表是一种常见的数据结构,用于存储一系列元素。在C语言中,链表通常由节点(Node)组成,每个节点包含元素值和指向下一个节点的指针。链表可以分为单向链表、双向链表和循环链表等不同类型。
常见的链表操作包括插入、删除、查找等。插入操作包括在链表头部、尾部或指定位置插入节点;删除操作包括删除指定位置或特定值的节点;查找操作可以遍历链表寻找指定值的节点。
链表相较于数组的优势在于动态插入和删除操作效率高,不需要提前知道数据量大小。但链表的缺点是查找特定元素的效率较低,需要遍历整个链表。
在实现链表时,需要注意内存管理,确保在释放节点时不会造成内存泄漏。同时,链表的结构设计也需要考虑头节点、尾节点、空链表等特殊情况的处理。
总的来说,链表是一种灵活且常用的数据结构,在实际应用中被广泛使用。熟练掌握链表的操作和实现方式对于提高程序效率和解决问题都具有重要意义。