赞
踩
向链表中增添元素,根据添加位置不同,可分为以下 3 种情况:
虽然新元素的插入位置不固定,但是链表插入元素的思想是固定的,只需做以下两步操作,即可将新元素插入到指定的位置:
next
指针指向插入位置后的结点;next
指针指向插入结点;例如,在链表 {1,2,3,4}
的基础上分别实现在头部、中间部位、尾部插入新元素 5,其实现过程如图所示:
注意:链表插入元素的操作必须是先步骤 1,再步骤 2;否则会导致插入位置后的这部分链表丢失,无法再实现步骤 1。
编写 C 语言代码来实现链表插入元素的操作:
//L为原链表,elem表示新数据元素,position表示新元素要插入的位置 Node *LinkInsert(Node *L, int elem, int position) { Node *temp = L; //创建临时结点temp //首先找到要插入位置的上一个结点 for(int i = 1; i< position; i++) { temp = temp->next; if(temp == NULL) { printf("插入位置无效\n"); return L; } } //创建插入结点a Node *a = (Node*)malloc(sizeof(Node)); a->elem = elem; //向链表中插入结点 a->next = temp->next; temp->next = a; return L; }
从链表中删除指定数据元素时,实则就是将存有该数据元素的节点从链表中摘除,然后释放该节点的存储空间。因此,从链表中删除数据元素需要进行以下 2 步操作:
从链表上摘除某节点的实现非常简单,只需找到该节点的直接前驱节点 temp
,执行一行程序:
temp->next = temp->next->next;
例如,从存有{1,2,3,4}
的链表中删除元素 3,则此代码的执行效果如图所示:
链表删除元素的 C 语言实现如下所示:
//L为原链表,position为要删除元素的值 Node *LinkDelete(Node *L, int position) { Node *temp = L; //遍历到被删除结点的上一个结点 for(int i = 1; i < position; i++) { temp = temp->next; if(temp == NULL) { printf("删除位置无效\n"); return L; } } Node *a = temp->next; //单独设置一个指针指向被删除结点,以防丢失 temp->next = temp->next->next; //删除某个结点的方法就是更改前一个结点的指针域 free(a); //手动释放该结点,防止内存泄漏 return L; }
在链表中查找指定数据元素,最常用的方法是:从表头依次遍历表中节点,用被查找元素与各节点数据域中存储的数据元素进行比对,直至比对成功或遍历至链表最末端的 NULL
(比对失败的标志)。
链表中查找特定数据元素的 C 语言实现代码为:
//L为原链表,elem表示被查找元素 int LocateElem(Node *L, int elem) { //新建一个指针temp,初始化为头指针L Node *temp = L; int position = 1; //由于头节点的存在,因此while中的判断为t->next while(temp->next) { temp = temp->next; if(temp->elem == elem) { return position; } position += 1; } //程序执行至此处,表示查找失败 return -1; }
更新链表中的元素,只需通过遍历找到存储此元素的节点,对节点中的数据域做更改操作即可。
链表中更新数据元素的 C 语言实现代码:
//更新函数,其中,position 表示更改结点在链表中的位置,newElem 为新的数据域的值
Node *LinkModify(Node *L, int position, int NewElem)
{
Node *temp = L;
temp = temp->next; //在遍历之前,temp指向首元结点
//遍历到待更新节点
for(int i = 1; i < position; i++)
{
temp = temp->next;
}
temp->elem = NewElem;
return L;
}
以上就是对链表中数据元素做"增删查改"的实现过程及 C 语言代码,如下是完整的代码清单:
#include<stdio.h> #include<stdlib.h> //链表中节点的结构 typedef struct node { int elem; //代表数据域 struct Node *next; //代表指针域,指向直接后继元素 }Node; //Node为节点名,每个节点都是一个Node结构体 //初始化链表的函数 Node *InitLink(); Node *InitLinkWithHead(); //用于输出链表的函数 void DisplayLink(Node *L); //链表插入的函数,p是链表,elem是插入的结点的数据域,position是插入的位置 Node *LinkInsert(Node *L, int elem, int position); //删除结点的函数,L代表操作链表,position代表删除节点的位置 Node *LinkDelete(Node *L, int position); //查找节点的函数,elem为目标结点的数据域的值 int LocateElem(Node *L, int Elem); //更新结点的函数,newElem为新的数据域的值 Node *LinkModify(Node *l, int OldElem, int NewElem); int main() { //初始化链表(1,2,3,4) printf("初始化链表为:\n"); Node *L = InitLinkWithHead(); DisplayLink(L); printf("在第4的位置插入元素5:\n"); L = LinkInsert(L, 5, 4); DisplayLink(L); printf("删除元素3:\n"); L = LinkDelete(L, 3); DisplayLink(L); printf("查找元素2的位置为:\n"); int position = LocateElem(L, 2); if (position == -1) { printf("没有该元素"); } else { printf("元素2的位置为:%d\n", position); } printf("更改第3的位置上的数据为7:\n"); L = LinkModify(L, 3, 7); DisplayLink(L); return 0; } Node *InitLink() { Node *p = NULL; //创建头指针 Node *temp = (Node*)malloc(sizeof(Node)); //创建首元节点 //首元节点先初始化 temp->elem = 1; temp->next = NULL; p = temp; //头指针指向首元节点 //从第二个节点开始创建 for(int i = 2; i < 5; i++) { //创建一个新节点并初始化 Node *a = (Node*)malloc(sizeof(Node)); a->elem = i; a->next = NULL; //将temp节点与新建立的a节点建立逻辑关系 temp->next = a; //指针temp每次都指向新链表的最后一个节点,其实就是 a节点,这里写temp=a也对 temp = temp->next; } //返回建立的节点,只返回头指针 p即可,通过头指针即可找到整个链表 return p; } Node *InitLinkWithHead() { Node *p = (Node*)malloc(sizeof(Node)); //创建一个头结点 Node *temp = p; //声明一个指针指向头结点 //生成链表 for(int i = 1; i < 5; i++) { Node *a = (Node*)malloc(sizeof(Node)); a->elem = i; a->next = NULL; temp->next = a; temp = temp->next; } return p; } //p为原链表,elem表示新数据元素,position表示新元素要插入的位置 Node *LinkInsert(Node *L, int elem, int position) { Node *temp = L; //创建临时结点temp //首先找到要插入位置的上一个结点 for(int i = 1; i< position; i++) { temp = temp->next; if(temp == NULL) { printf("插入位置无效\n"); return L; } } //创建插入结点a Node *a = (Node*)malloc(sizeof(Node)); a->elem = elem; //向链表中插入结点 a->next = temp->next; temp->next = a; return L; } //p为原链表,add为要删除元素的值 Node *LinkDelete(Node *L, int position) { Node *temp = L; //遍历到被删除结点的上一个结点 for(int i = 1; i < position; i++) { temp = temp->next; if(temp == NULL) { printf("删除位置无效\n"); return L; } } Node *a = temp->next; //单独设置一个指针指向被删除结点,以防丢失 temp->next = temp->next->next; //删除某个结点的方法就是更改前一个结点的指针域 free(a); //手动释放该结点,防止内存泄漏 return L; } //L为原链表,elem表示被查找元素 int LocateElem(Node *L, int elem) { //新建一个指针temp,初始化为头指针L Node *temp = L; int position = 1; //由于头节点的存在,因此while中的判断为t->next while(temp->next) { temp = temp->next; if(temp->elem == elem) { return position; } position += 1; } //程序执行至此处,表示查找失败 return -1; } //更新函数,其中,add 表示更改结点在链表中的位置,newElem 为新的数据域的值 Node *LinkModify(Node *L, int position, int NewElem) { Node *temp = L; temp = temp->next; //在遍历之前,temp指向首元结点 //遍历到待更新结点 for(int i = 1; i < position; i++) { temp = temp->next; } temp->elem = NewElem; return L; } void DisplayLink(Node *L) { Node* temp = L;//将temp指针指向头结点 //只要temp指针指向的结点的next不是Null,就执行输出语句。 while (temp->next) { temp = temp->next; printf("%d ", temp->elem); } printf("\n"); }
代码运行结果:
初始化链表为:
1 2 3 4
在第4的位置插入元素5:
1 2 3 5 4
删除元素3:
1 2 5 4
查找元素2的位置为:
元素2的位置为:2
更改第3的位置上的数据为7:
1 2 7 4
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。