单链表的基本操作
单链表的基本操作
单链表的基本操作
《》⼀节我们学习了如何使⽤存储数据元素,以及如何使⽤ C 语⾔创建链表。本节将详细介绍对链表的⼀些基本操作,包括对链表中数据的添加、删除、查找(遍历)和更改。
注意,以下对链表的操作实现均建⽴在已创建好链表的基础上,创建链表的代码如下所⽰:
1. //声明节点结构
2. typedef struct Link{
3. int elem;//存储整形元素
4. struct Link *next;//指向直接后继元素的指针
5. }link;
6. //创建链表的函数
7. link * initLink(){
8. link * p=(link*)malloc(sizeof(link));//创建⼀个头结点
9. link * temp=p;//声明⼀个指针指向头结点,⽤于遍历链表
10. //⽣成链表
11. for (int i=1; i<5; i++) {
12. //创建节点并初始化
13. link *a=(link*)malloc(sizeof(link));
14. a->elem=i;
15. a->next=NULL;
16. //建⽴新节点与直接前驱节点的逻辑关系
17. temp->next=a;
18. temp=temp->next;
19. }
20. return p;
21. }
从实现代码中可以看到,该链表是⼀个具有头节点的链表。由于头节点本⾝不⽤于存储数据,因此在实现对链表中数据的"增删查改"时要引起注意。
链表插⼊元素
同⼀样,向链表中增添元素,根据添加位置不同,可分为以下 3 种情况:
JAVA数据结构——单链表的操作
单链表的操作
方法一:
package ch02;
(1)建立结点类Node.java
public class Node {
public Object data;//存放结点数据值
public Node next;//存放后继结点
//无参构造函数
public Node(){ this(null,null);
}
//只有结点值的构造函数
public Node(Object data){ this(data,null);
}
//带有节点值和后继结点的构造函数
public Node(Object data,Node next){ this.data=data;
this.next=next;
}
}
(2)建立链表及操作LinkList.java
package ch02;
import java.util.Scanner;
public class LinkList implements IList{
public Node head;//单链表的头指针
//构造函数初始化头结点
public LinkList(){
head=new Node();
}
//构造函数构造长度为n的单链表
public LinkList(int n,boolean Order) throws Exception{ this();
if(Order)
create1(n); //头插法顺序建立单链表
else
create2(n); //尾插法逆序建立单链表
}
//头插法顺序建立单链表
public void create1(int n) throws Exception{
单链表基本操作
单链表基本操作
在计算机科学里,链表是一种常见的数据结构,它可以用来解决各种
复杂的问题。其中,单链表是最常见的一种,它由一系列节点组成,
每个节点包含了一个数据元素和一个指针,指向下一个节点。这篇文
章将介绍单链表的基本操作,包括创建、插入、删除和遍历等。
创建单链表
创建单链表是基本操作之一,它有两种方法:头插法和尾插法。
头插法是从链表的头节点开始,逐个将新节点插入。具体来说,创建
一个空链表,设置一个头节点,将头节点的指针指向空;依次输入新
节点,将新节点的指针指向表头,将表头的指针指向新节点。这样,
每插入一个新节点就成为了新的表头,即最后插入的节点为新的表头。
尾插法则是从链表的尾节点开始,逐个将新节点插入。具体来说,创
建一个空链表,设置一个头节点,将头节点的指针指向空;依次输入
新节点,将新节点的指针指向空,将最后一个节点的指针指向新节点。这样,最后插入的节点为尾节点,它的指针值为空。
插入节点
插入节点是指在单链表的任意位置插入一个新节点。插入节点的前提是找到插入位置,可以通过遍历单链表来查找插入位置。插入新节点的基本步骤如下:
1、创建新节点;
2、将新节点的指针指向待插入节点的后继节点;
3、将待插入节点的指针指向新节点。
删除节点
删除节点是指删除单链表中的任意节点。删除节点的前提是找到删除的节点位置,可以通过遍历单链表来查找删除位置。删除节点的基本步骤如下:
1、找到要删除的节点;
2、将该节点的前驱节点的指针指向该节点的后继节点;
3、删除该节点。
遍历节点
遍历节点是指按照链表的顺序依次访问链表中的各个节点。遍历节点
单链表——基本操作
单链表——基本操作
1.获取链表第i个数据的算法思路
1. 声明⼀个结点p指向链表第⼀个结点,初始化j从1开始
2. 当j<i时,就遍历链表,让p的指针向后移动,不断指向下⼀结点,j累加1
3. 若到链表末尾p为空,则说明第i个元素不存在
4. 否则查找成功,返回结点p的数据
2.单链表第i个数据插⼊结点的算法思路
1. 声明⼀结点p指向链表第⼀个结点,初始化j从1开始
2. 当j<i时,就遍历链表,让p的指针向后移动,不断指向下⼀结点,j累加1
3. 若到链表末尾p为空,则说明第i个元素不存在
4. 否则查找成功,在系统中⽣成⼀个空结点s
5. 将数据元素e赋值给s->data
6. 单链表的插⼊标准语句s->next=p->next;p->next=s
7. 返回成功
3.单链表第i个数据删除结点的算法思路
1. 声明⼀结点p指向链表第⼀个结点,初始化j从1开始
2. 当j<i时,就遍历链表,让p的指针向后移动,不断指向下⼀结点,j累加1
3. 若到链表末尾p为空,则说明第i个元素不存在
4. 否则查找成功,将欲删除的结点p->next赋值给q
5. 单链表的删除标准语句p->next=q->next
6. 将q结点中的数据赋值给e,作为返回
7. 释放q结点
8. 返回成功
分析⼀下刚才我们讲解的单链表插⼊和删除算法,我们发现,它们其实都是由两部分组成:第⼀部分就是遍历查找第i个结点;第⼆部分就是插⼊和删除结点。
4.单链表整表创建的算法思路
1. 声明⼀结点p和计数器变量i
数据结构—单链表的基本操作
数据结构—单链表的基本操作#include<iostream>
using namespace std;
//单链表的节点定义
typedef struct LNode {
int data;
struct LNode *next;
}LNode, *LinkList; //LinkList 等价于 LNode*, LinkList强调这是链表,LNode强调这是节点
//按位序插⼊(带头节点)
bool ListInsert(LinkList &L, int i, int e)
{
if (i<1) return false;
LNode *p = L;
int j = 0;
while (p!=null && j<i-1){ //循环找到第i-1个节点
p = p->next;
j ++;
}
return InsertNextNode(p, e); //指定节点的后插
}
//指定节点的后插操作:时间复杂度O(1)
bool InsertNextNode(LNode *p, int e)
{
if (p == null) return false;
LNode *s = (LNode*)malloc(sizeof(LNode));
s->data = e;
s->next = p->next;
p->next = s;
return true;
}
//指定节点的前插操作:时间复杂度O(1)
bool InsertPriorNode(LNode *p, int e)
{
if (p == null) return false;
单链表的 基本操作
单向链表
单向链表的基本操作,创建一个由6个节点组成的单向链表,显示链表中每个节点的数据,并且做增加、删除、查找节点以及计算单链表的长度等处理。
➢需求分析:
1.功能
(1)用尾插法创建一带头结点的由6个节点组成的单向链表:从键盘读入一组整数,作为单链表中的元素,输入完第6个结点后结束;将创建好的单链表元素依次输出到屏幕上。
(2)显示链表中每个节点的数据
(3)从键盘输入一个数,查找在以上创建的单链表中是否存在该数;如果存在,显示它的位置,即第几个元素;如果不存在,给出相应提示如“No found node!”。
(4)在上述的单链表中的指定位置插入指定数据,并输出单链表中所有数据。
(5)删除上述单链表中指定位置的结点,并输出单链表中所有数据。
(6)求单链表的长度并输出.
2.输入要求
先输入单链表中结点个数n,再输入单链表中所有数据,在单链表中需查找的数据,需插入的数据元素的位置、值,要删除的数据元素的位置。
3。测试数据
单链表中所有数据:12,23,56,21,8,10
在单链表中需查找的数据:56;24
插入的数据元素的位置、值:1,28;7,28;0,28
要删除的数据元素的位置:6
➢概要设计:
1.算法思想:由于在操作过程中要进行插入、删除等操作,为运算方便,选用带头结点的单链
表作数据元素的存储结构.对每个数据元素,由一个数据域和一个指针域组成,数据域放输入的数据值,指针域指向下一个结点。
2.数据结构:
单链表结点类型:
typedef struct Liistnode {
int data;
struct Listnode *next;
单链表的基本操作
{int n;
struct Innode *pt;
printf("请输入创建单链表结点的个数:");
scanf("%d",&n);
while(n<0)
{
printf("结点个数必须大于等于0,请重新输入:");
scanf("%d",&n);
}
pt=createlist(n);
traverslist(pt);
data next
head
1
2
3
当i=4时: p_new=(struct Innode *)malloc(sizeof(struct Innode)); p_new->data=4;
data next
head
1
2
3
4
tail->next=p_new;
tail
head
data next
1
2
p_new 3
xx冬 xx开放大学xx分校
动态建立下图所示的n个结点的单链表,并输出。(尾插法)
头指针
head
数据域 指针域
data next
1
2
首结点
#include <stdio.h> #include <stdlib.h>
单链表的基本操作
一、实验目的
1.掌握线性表的链式存贮结构及基本操作,深入了解链表的基本特性,以便在实际问题背景下灵活运用它们。
2.巩固该存贮结构的构造方法,深入了解和灵活掌握链表的插入,删除等操作。
二、实验环境
1.硬件:每个学生需配备计算机一台。
2.软件:windows操作系统+Turbo C。
三、实验要求
1.定义一链表类型,并定带有头结点的单链表。
2.将教材中链表的建立,初始化,插入,删除等函数实现。
3.链表能够存储10名学生的基本信息(包括姓名、学号和成绩)。
4.由主函数按照用户要求对各个链表操作访问。
5.每次操作之前要有明确的说明,操作后要输出操作结果。
6.分析链表的插入,删除。
四、实验内容
1.完成链表操作用到的函数
InitList(&L)
操作结果:构造一个空线性表L。
ListInsert(&L,i,e)
初始条件:线性表L已存在,1<=i<=ListLength(L)+1。
操作结果:在L中第i个位置之前插入新的数据元素e,L的长度加1。ListDelete(&L,i,&e)
初始条件:线性表L已存在且非空,1<=i<=ListLength(L)。
操作结果:删除L中第i个数据元素,并用e返回其值,L的长度减1。
五、源程序
六、运行结果
主界面
输入数据
数据显示
数据插入
数据删除
七、总结
通过本次实验,我对线性表的链式表现与实现有了更深入的了解,理论联系实践的学习了链表的插入及删除。
单链表的基本操作
上机实验报告
学院:计算机与信息技术学院
专业:计算机科学与技术(师范)课程名称:数据结构
实验题目:单链表建立及操作
班级序号:师范1班
学号:201421012731
学生姓名:邓雪
指导教师:杨红颖
完成时间:2015年12月25号
一、实验目的:
(1)动态地建立单链表;
(2)掌握线性表的基本操作:求长度、插入、删除、查找在链式存储结构上的实现;
(3)熟悉单链表的应用,明确单链表和顺序表的不同。
二、实验环境:
Windows 8.1
Microsoft Visual c++ 6.0
三、实验内容及要求:
建立单链表,实现如下功能:
1、建立单链表并输出(头插法建立单链表);
2、求表长;
3、按位置查找
4、按值查找结点;
5、后插结点;
6、前插结点
7、删除结点;
四、概要设计:
1、通过循环,由键盘输入一串数据。创建并初始化一个单链表。
2、编写实现相关功能函数,完成子函数模块。
3、调用子函数,实现菜单调用功能,完成顺序表的相关操作。
五、代码:
#include
#include
typedef char datatype;
typedef struct node
{
datatype data;
struct node *next;
}linklist;
linklist *head,*p;
//头插法建立单链表
linklist *Creatlistf()
{
char ch;
linklist *head,*s;
head=NULL;
ch=getchar();
printf("请输入顺序表元素(数据以$结束):\n");
while(ch!='$')
单链表基本操作
#include
#include
typedef struct node
{
char data;
struct node *next;
}LNode;
LNode *CreateLinkList()
{
LNode *head,*p,*q;
char x;
head=(LNode*)malloc(sizeof(LNode));
head->next=NULL;
p=head;
q=p;
printf("lnput any char sting:\n");
scanf("%c",&x);
while(x!='\n')
{
p=(LNode*)malloc(sizeof(LNode));
p->data=x;
p->next=NULL;
q->next=p;
q=p;
scanf("%c",&x);
}
return head;
}
int Length_LinkList(LNode *head) //求表长
{
LNode *p=head;
int i=0;
while(p->next!=NULL)
{
p=p->next;
i++;
}
return i;
}
LNode *Get_LinkList(LNode *head,int i) //按序号查找
LNode *p=head;
int j=0;
while(p!=NULL&&j
{
p=p->next;
j++;
}
return p;
}
LNode *Locate_LinkList(LNode *head,char x) //按值查找
{
LNode *p=head->next;
while(p!=NULL&&p=x)
{
单链表的基本操作
创建链表:
status create(LinkList &L)
{
int i,n;
LinkList p;
printf("please input the length of the LinkList:");
scanf("%d",&n);
L=(LinkList)malloc(sizeof(LNode));
L->next=NULL; //先建立一个带头结点的单链表
printf("please input the data of the LinkList:");
for(i=1;i<=n;i++)
{
p=(LinkList)malloc(sizeof(LNode));//生成新结点
scanf("%d",&p->data); //输入元素值
p->next=L->next;//insert到表头
L->next=p;
}
return ok;
}
排序:
status order(LinkList &L)
{
LinkList p,q,small;
for(p=L->next;p->next!=NULL;p=p->next) //外循环
{
small=p;
//起始时设small与首元素一致
for(q=p->next;q!=NULL;q=q->next)//内循环,使small指向最小值 {
if(small->data>q->data)
small=q;
}
if(small!=p)//判断small与p是否一致,如果不一致则交换small与p 的值
单链表及其基本操作
第四讲
2) 尾插法建表
s 指向新申请的结点空间 L r (a) 建空表 s (b) 申请新结点并赋值 c1 s--data =c 1
① r --next =s;
L r c1 s L c1 c2
②
(c) 插入第一个结点
r s r=s;r始终指向单链表的表尾
第四讲
单链表及其基本操作
2011年10月23日
计算机科学与技术系
1
第四讲
单链表中每个结点包括两个域:数据域 数据域用来存储 数据域 结点的值;指针域 指针域用来存储数据元素的直接后继 指针域 的地址(或位置)。链表正是通过每个结点的指 针域将线性表的n个结点按其逻辑顺序链接在一 起。由于链表的每个结点只有一个指针域,故将 这种链表又称为单链表 单链表。 单链表
2011年10月23日
计算机科学源自文库技术系
19
第四讲
int InsList(LinkList L, int i, ElemType e) { /*在带头结点的单链表L中第i个位置插入值为e的新结点 */ Node *pre, *s; int k; pre=L; k=0; while(pre!=NULL&&k<i-1) /* 在第i个元素之前插入, 则先找到第i-1个数据元素的存储位置, 使指 针pre指向它 */ {pre=pre->next; k=k+1; }
单链表的基本操作
#include<stdlib.h>
#include<stdio.h>
typedef int ElemType;/* 定义ElemType为int类型*/
#define TRUE 1
#define FALSE 0
#define flag -1/* 单链表的结点类型*/
typedef struct LNode
{
ElemType data;
struct LNode *next;
} LNode,*LinkList;//LNode是此结构体的类型名,而LInkList是结构体指针的类型名
LinkList LinkListInit()/* 建立一个单链表*/
{
LinkList L;
L=(LinkList)malloc(sizeof(LNode));
L->next=NULL;
return L;
}
void LinkListClear(LinkList L)/* 清空单链表*/
{
L->next=NULL;
}
int LinkListEmpty(LinkList L)/* 检查单链表是否为空*/
{
if (L->next==NULL)
return TRUE;
else return FALSE;
}
void LinkListTraverse(LinkList L)/* 遍历单链表*/
{
LinkList p;//遍历是将顺序表中的元素都调用一次。
p=L->next;
while (p!=NULL)
{
printf("%d ",p->data);
p=p->next;
单链表的实现及其基本操作
单链表的实现及其基本操作
结点的引⼊
链表是⼀种链式存储结构,链式存储结构的特点是⽤⼀组任意的存储单元存储数据元素。为了能正确表⽰数据元素之间的线性关系,需引⼊结点概念。⼀个结点表⽰链表中的⼀个数据元素,节点中除了储存数据元素的信息,还必须存放指向下⼀个节点的的指针(单、双链表的最后⼀个节点除外,它们存储的是⼀个空指针NULL)
结点的结构如下图所⽰:
代码如下:
1 typedef struct node{
2int data;
3struct node* pNext;
4 }Node, *PNode;
View Code
注:这⾥假设结点中储存的是整型 (int) 的数据
单链表由多个结点依次连接⽽成,我们不难想象出它结构:
我们注意到:在第⼀个结点的前⾯多了⼀个头结点,这是为了处理空表的⽅便⽽引⼊的,它的指针指向链表的第⼀个结点,⽽它的data域不存放任何信息。
单链表的基本操作
1.创建链表
1 PNode createList()
2 {
3int len, value;
4
5 PNode pHead = (PNode)(malloc(sizeof(Node)));
6 PNode pTail = pHead;
7 pTail->pNext = NULL;
8
9 printf("请输⼊你要的节点个数:");
10 scanf("%d", &len);
11for(int i=1;i<=len;i++){
12 printf("请输⼊第%d个节点的值:", i);
13 scanf("%d", &value);
单链表基本操作
#include<stdio.h>
#include<stdlio.h>
typedef struct node
{
char data;
struct node *next;
}LNode;
LNode *CreateLinkList()
{
LNode *head,*p,*q;
char x;
head=(LNode*)malloc(sizeof(LNode));
head->next=NULL;
p=head;
q=p;
printf("lnput any char sting:\n");
scanf("%c",&x);
while(x!='\n')
{
p=(LNode*)malloc(sizeof(LNode));
p->data=x;
p->next=NULL;
q->next=p;
q=p;
scanf("%c",&x);
}
return head;
}
int Length_LinkList(LNode *head) //求表长
{
LNode *p=head;
int i=0;
while(p->next!=NULL)
{
p=p->next;
i++;
}
return i;
}
LNode *Get_LinkList(LNode *head,int i) //按序号查找
LNode *p=head;
int j=0;
while(p!=NULL&&j<i)
{
p=p->next;
j++;
}
return p;
}
LNode *Locate_LinkList(LNode *head,char x) //按值查找
单链表的基本操作
插入
if(!p||j>i-1) return ERROR; s=(LinkList)malloc(sizeof(LNode)); s->data=e;//数据域赋值 s->next=p->next;//把s插入单链表中 p->next=s; return OK; }
归并两个链表(条件)
void MergeList_L(LinkList &La, LinkList &Lb,LinkList &Lc) { LinkList pa,pb,pc; pa=La->next;//第一个结点的地址赋给pa pb=Lb->next; Lc=pc=La;//以pa的头结点作为Lc的头结点
归并两个链表
while(pa&&pb) {//La和Lb中均有结点的时候 if(pa->data<=pb->data) { //归并不需要只留一个的相同元素 pc->next=pa; pc=pa; pa=pa->next; } else { pc->next=pb; pc=pb; pb=pb->next; } } pc->next=pa?pb:pb; free(Lb); }
得到第某个位置的数据元素
Status GetElem_L(LinkList L,int i,ElemType &e)
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
10)调用头插法的函数,分别输入10,20,分别回车:
11)调用尾插法的函数,分别输入30,40
12)查找单链表的第四个元素:
13)主函数中传入参数,删除单链表的第一个结点:
14)主函数传入参数,删除第0个未位置的元素,程序报错:
15)最后,输出单链表中的元素:
return 0;
}
6)编译,连接,运行源代码:
7)输入8,回车,并输入8个数,用空格分隔开,根据输出信息,可以看出,链表已经拆分为两个
五、实验总结
1.单链表采用的是数据+指针的表示形式,指针域总是指向下一个结
点(结构体)的地址,因此,在内存中的地址空间可以是不连续的,操作比顺序存储更加的方便
2.单链表使用时,需要用malloc函数申请地址空间,最后,删除元
素时,使用free函数释放空间