目录
1、链表
链表顾名思义是一种链式的存储结构,使用链表不在需要一整块连续的内存空间,这大大增加了内存空间的利用率,并且链表也是我们后续能够顺利学习其它数据结构的基础。
链表的一个节点是由两部分组成的:数据域 、指针域,数据域存放的是数据,指针域存放的是下一个节点的地址,多个节点通过指针域相连形成了一条“链”。
头节点后的第一个节点称为首元节点,头节点中的数据域可以存放链表节点的个数也可以不存放数据,当然头节点不是必须的,头节点的上存在可以使我们更方便的对链表进行 增、删、改、查。
节点的代码实现需要借助结构体(结构体在数据结构中无处不在)
typedef struct Node
{
int data; //数据域
struct Node* next; //指针域
}node;
int main()
{
node*head = (node*)malloc(sizeof(node)); //创建了一个 head 节点
free(head);
return 0;
}
2、创建链表(带头节点)
2.1、创建头节点并初始化
node* headPointer()
{
node* head = (node*)malloc(sizeof(node)); //为头节点分配空间
if (!head)
{
printf("头节点创建失败");
exit(0);
}
//初始化头节点
head->next = NULL;
head->data = 0; //链表节点个数(不包含头节点)
printf("头节点创建成功\n");
return head;
}
2.2、创建链表的节点并连接链表节点
链表节点的连接方式有两种:尾插法、头插法,这两种方法将在下面详细分析
//创建链表(有头节点)
void createLink(node* head,int*arr,int i) //这里的i是main函数中的int数组的大小
{
//movePointer为移动指针,移动指针指向头节点
node* move_Pointer = head;
while (head->data!=i)
{
node* newNode = (node*)malloc(sizeof(node));
if (newNode == NULL)
{
printf("新节点创建失败");
exit(0);
}
newNode->data = arr[head->data]; //为新节点赋值
newNode->next = NULL; //初始化新节点的指针域
// 尾插法----------------------------------------------------
move_Pointer->next = newNode;
move_Pointer = newNode;
//-----------------------------------------------------------
//头插法------------------------------------------------------
//newNode->next = move_Pointer->next;
//move_Pointer->next = newNode;
//-----------------------------------------------------------
head->data += 1;
}
printf("链表创建成功\n");
}
尾插法:
核心代码
move_Pointer->next = newNode;
move_Pointer = newNode;
文字描述:
1、通过 node* movePointer = head; 使move_Pointer指向头节点head
2、node* newNode = (node*)malloc(sizeof(node)); 的到一个新的节点 (1号新节点)
3、执行 move_Pointer->next=newNode; 使头节点的指针域指向新节点(1号新节点),实现头节点与新节点的连接
4、执行 move_Pointer=newNode; 使move_Pointer从指向头节点变为指向新节点
5、whiel()循环得到第2个新节点(2号新节点)
6、重复第 3 步使 1号新节点与2号新节点相连
7、重复第 4 步使move_Pointer从指向1号新节点变为指向2号新节点
8、重复执行 2–4步,链表形成
头插法:
核心代码
newNode->next = move_Pointer->next;
move_Pointer->next = newNode;
文字描述:
1、通过 node* move_Pointer = head; 使move_Pointer指向头节点head
2、node* newNode = (node*)malloc(sizeof(node)); 的到一个新的节点 (1号新节点)
3、执行 newNode->next = move_Pointer->next; 使头节点和 1号新节点都指向 NULL
4、执行 move_Pointer->next = newNode; 使头节点的指针域指向 1号新节点
5、重复第 2 步得到 2 号新节点
6、重复第 3 步使新节点的指针域(newNode->next)指向 1号节点 使的2号新节点与一号新节点相连
7、执行第 4 步使得头指针指针域指向 2 号新节点
8、重复2–4步,链表完成
在这里我们发现,尾插法的移动指针(move_Pointer)始终始终是指向链表的最后一个节点的,而头插法的移动指针(move_Pointer)是始终指向头节点的
3、遍历链表
//遍历链表
void travLink(node* head)
{
node* move_Pointer = head->next; //移动指针指向首元节点
while (move_Pointer!=NULL)
{
printf("%d\n", move_Pointer->data);
move_Pointer = move_Pointer->next; //移动指针指向当前节点的后继节点
}
}
4、查找节点
查找节点是链表后续操作的基础,链表的增、删、改,都需要找到需要操作的节点的位置。
//查找链表的节点(本次查找不是通过节点中的数据查找的,而是通过节点的序号进行查找)
node* findNode(node* head)
{
int i;
int j = 1;
node* move_Pointer = head->next; //移动指针指向首元节点
//printf("你要查找第几个节点\n");
scanf_s("%d", &i);
if (i <= head->data)
{
while (move_Pointer!= NULL)
{
if (i == 0) //在头节点后插入新节点
return head;
if (i == j) //在第i个节点后面添加节点
{
return move_Pointer;
}
else
{
move_Pointer = move_Pointer->next; //move_Pointer指向当前节点的后继节点
j += 1;
}
}
}
else
{
printf("没有你要查找的节点");
exit(0);
}
}
5、添加节点
//添加链表的节点
void addNode(node*head)
{
int i;
printf("你要在第几个节点后添加新节点:");
node* tarNode = findNode(head); //节点查找
node* P;
P = tarNode->next; //P指向添加的位置
node* newNode = (node*)malloc(sizeof(node)); //要添加的新节点
if (!newNode)
{
printf("新添加的节点创建失败\n");
exit(0);
}
printf("你要添加的数据是:");
scanf_s("%d", &i);
//初始化新节点--------
newNode->next = NULL;
newNode->data = i;
//------------------
tarNode->next = newNode;
newNode->next = P;
head->data += 1; //节点数加一
}
6、删除节点
//删除节点
void delNode(node* head)
{
printf("你要删除第几个节点:");
node* tarNode = findNode(head); //查找链表的节点
node* P; //过渡指针
if (!tarNode)
{
printf("没有找到删除的位置\n");
exit(0);
}
if (tarNode->next == NULL) //删除最后一个节点
{
free(tarNode); //释放被删除节点的存储空间
head->data -= 1; //节点数减一
printf("删除完成\n");
}
else
{
P = tarNode->next->next;
free(tarNode->next); //释放被删除节点的存储空间
tarNode->next = P;
head->data -= 1; //节点数减一
printf("删除完成\n");
}
}
7、更改节点数据
//更改节点数据
void chanData(node* head)
{
node* tarNode = findNode(head);
printf("你要将 %d 更改为:", tarNode->data);
scanf_s("%d", &(tarNode->data));
printf("数据更改完成\n");
}
8、排序(冒泡排序,只交换节点数据)
//排序(冒泡排序)
void sortNode(node* head)
{
if (head->data == 0)
exit(0);
int i = 0;
int j = 0;
int elem;
node* P;
node* P1;
node* P2;
if (head->data == 0)
exit(0);
for (i = 0; i < head->data - 1; i++)
{
P = head->next;
for (j = 0; j < head->data - i - 1; j++)
{
P1 = P;
P2 = P1->next;
if (P1->data > P2->data)
{
elem = P2->data;
P2->data = P1->data;
P1->data = elem;
}
P = P->next;
}
}
}
9、完整代码
#include<stdio.h>
#include<stdlib.h>
typedef struct Node
{
int data; //数据域
struct Node* next; //指针域
}node;
node* headNode(); //创建头节点,并初始化
void createLink(node* head, int* arr); //创建链表(有头节点)
node* findNode(node* head); //查找链表的节点
void addNode(node* head); //添加节点
void travLink(node* head); //遍历链表
void delNode(node* head); //删除节点
void chanData(node* head); //更改节点数据
void sortNode(node* head); //排序(冒泡排序)
int main()
{
int i = 0;
int arr[] = { 23,34,45,56,67,78,89 };
node* head = headPointer(); //创建头节点,并初始化
createLink(head, arr); //创建链表(有头节点)
addNode(head); //添加新的节点
delNode(head); //删除节点
sortNode(head); //排序(冒泡排序)
travLink(head); //遍历链表
free(head);
return 0;
}
//创建头节点,并初始化
node* headNode()
{
node* head = (node*)malloc(sizeof(node)); //查找链表的节点
if (!head)
{
printf("头节点创建失败");
exit(0);
}
head->next = NULL;
head->data = 0;
printf("头节点创建成功\n");
return head;
}
//创建链表(有头节点)
void createLink(node* head,int*arr)
{
node* move_Pointer = head; //移动指针指向头节点
while (head->data!=7)
{
node* newNode = (node*)malloc(sizeof(node));
if (newNode == NULL)
{
printf("新节点创建失败");
exit(0);
}
newNode->data = arr[head->data]; //为新节点赋值
newNode->next = NULL; //初始化新节点的指针域
// 尾插法----------------------------------------------------
move_Pointer->next = newNode;
move_Pointer = newNode;
//-----------------------------------------------------------
//头插法------------------------------------------------------
//newNode->next = move_Pointer->next;
//move_Pointer->next = newNode;
//-----------------------------------------------------------
head->data += 1;
}
printf("链表创建成功\n");
}
//遍历链表
void travLink(node* head)
{
node* move_Pointer = head->next;
while (move_Pointer!=NULL)
{
printf("%d\n", move_Pointer->data);
move_Pointer = move_Pointer->next;
}
}
//更改节点数据
void chanData(node* head)
{
node* tarNode = findNode(head);
printf("你要将 %d 更改为:", tarNode->data);
scanf_s("%d", &(tarNode->data));
printf("数据更改完成\n");
}
//删除节点
void delNode(node* head)
{
printf("你要删除第几个节点:");
node* tarNode = findNode(head); //查找链表的节点
node* P;
if (!tarNode)
{
printf("没有找到删除的位置\n");
exit(0);
}
if (tarNode->next == NULL)
{
free(tarNode);
head->data -= 1;
printf("删除完成\n");
}
else
{
P = tarNode->next->next;
free(tarNode->next);
tarNode->next = P;
head->data -= 1;
printf("删除完成\n");
}
}
//查找链表的节点
node* findNode(node* head)
{
int i;
int j = 1;
node* move_Pointer = head->next;
//printf("你要查找第几个节点\n");
scanf_s("%d", &i);
if (i <= head->data)
{
while (move_Pointer!= NULL)
{
if (i == 0)
return head;
if (i == j)
{
return move_Pointer;
}
else
{
move_Pointer = move_Pointer->next;
j += 1;
}
}
}
else
{
printf("没有你要查找的节点");
exit(0);
}
}
//排序(冒泡排序)
void sortNode(node* head)
{
if (head->data == 0)
exit(0);
int i = 0;
int j = 0;
int elem;
node* P;
node* P1;
node* P2;
if (head->data == 0)
exit(0);
for (i = 0; i < head->data - 1; i++)
{
P = head->next;
for (j = 0; j < head->data - i - 1; j++)
{
P1 = P;
P2 = P1->next;
if (P1->data > P2->data)
{
elem = P2->data;
P2->data = P1->data;
P1->data = elem;
}
P = P->next;
}
}
}
//添加链表的节点
void addNode(node*head)
{
int i;
printf("你要在第几个节点后添加新节点:");
node* tarNode = findNode(head);
node* P;
if (!tarNode)
{
printf("没有查找到添加位置\n");
exit(0);
}
P = tarNode->next;
node* newNode = (node*)malloc(sizeof(node));
if (!newNode)
{
printf("新添加的节点创建失败\n");
exit(0);
}
printf("你要添加的数据是:");
scanf_s("%d", &i);
newNode->next = NULL;
newNode->data = i;
tarNode->next = newNode;
newNode->next = P;
head->data += 1;
}
原文地址:https://www.jb51.cc/wenti/3288005.html
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。