单链表的基本操作

news2024/11/26 22:33:09

此代码不可运行,含伪代码。

一、 定义数据域

typedef struct{

char num[8];

char name[8];

int score;

}ElemType;

二、 定义一个链表

typedef struct LNode{

ElemType data; //链表中结点的数据域

struct Lnode *next; //为指向下一个结点的指针域,并且所指向的也是Lnode型的数据

}LNode,*LinkList;

//LinkList为指向结构体Lnode的指针类型,可定义链表L: LinkList p;等价于 LNode *p;

三、建立一个空表

Status InitList_L(LinkList &L){

L = new LNode; //生成新结点作为头结点,用头指针L指向头结点

// L = (LinkList)malloc(sizeof(LNode));

L->next = NULL; //将头结点的指针域置空

return OK;

}

四、判断链表是否为空

int ListEmpty(LinkList L){ //若L为空表,则返回1,否则返回0

if(L->next) //非空

return 0;

else

return 1;

}

五、销毁链表

Status DestroyList_L(LinkList &L){ //销毁单链表L

Lnode *p;

// LinkList p;

while(L){ //判断L指向的后一个结点是否为空

p = L;

L = L->next;

delete p; //等同于free(p);

}

return OK;

}

六、清除链表的内容,但保留链表的结构

Status ClearList(LinkList &L){ //将L重置为空表

Lnode *p,*q; //或 LinkList p,q;

p = L->next; //这指向的还只是头结点,并不是首元结点

while(p){ //判断下一结点是否为空

q = p->next;

delete p; //等同于free(p); 只是将p的内存给释放了

p = q;

}

L->next = NULL; //令头结点指针域为空

return OK;

}

七、计算链表的长度

int ListLength_L(LinkList L){ //返回L中数据元素的个数

LinkList p; //Lnode *p;

p = L->next;//L为头结点,L->next为L的指针域,所指向的为首元结点的地址。所以p指向的是第一个结点即首元结点。

int i=0;

while(p){ //遍历单链表,统计结点数

i++;

p = p->next; //p指向下一结点

}

return i;

}

八、根据指定位置i,取链表中对应的值e

Status GetElem_L(LinkList L,int i,ElemType &e){ //取值。获取线性表L中的某个数据元素的内容,通过变量e返回

p = L->next; //初始化,让p指向首元结点

int j=1;

while(p && j<i){ //向后扫描,直到p指向的第i个元素 或 p为空

p = p->next;

++j;

}

if(!p || j>i) //若第i个元素不存在

return ERROR;

e = p->data; //取第i个元素

return OK;

}

九、根据给出的e值,返回链表中对应的地址

Lnode *LocateElem_L(LinkList L,ElemType e){ //在线性表L中查找值为e的数据元素

//若找到,则返回L中值为e的数据元素的地址,查找失败则返回NULL。

p = L->next;

while(p && p->data!=e) //p不为空,且没有找到e值

p = p->next; //指向下一个

return p;

}

十、根据给出的e值,返回链表L中该值的位置序号

int LocateElem_L1(LinkList L,ElemType e){ //在线性表L中查找值为e的数据元素的位置序号

//返回L中值为e的数据元素的位置序号

p = L->next;

int j=1; //从头开始计数

while(p && p->data!=e){

p = p->next;

j++;

}

if(p) //如果p值为空,则返回0,否则返回位置序号

return j;

else

return 0;

}

十一、根据给出的位置i,在链表L中插入元素e

Status ListInsert_L(LinkList &L,int i,ElemType e){ //插入。在L中第i个元素之前插入数据元素e

//插入算法中i的合理取值范围是1~n+1。

p = L; //此处p为头结点开始,以防有人要在第一个元素前插入数据元素e

int j = 0;

while(p && j<i-1){ //寻找第i-1个结点。若退出循环,即j=i-1或者p为空。

p = p->next;

++j;

}

if(!p || j>i-1) //若i大于表长+1 或者小于1,则插入位置非法

return ERROR;

这后面几步为关键步骤!!!

s = new LNode; 先生成新结点s

s->data = e; 再将结点s的数据域置为e

s->next = p->next; 先将第i个结点,放在新结点的后面。即新结点指向第i个结点,作为新结点的后继。

p->next = s; 再将新结点放在,第i-1个结点的后面。即第i-1个结点指向新结点,作为新结点的前驱。

return OK;

}

十二、根据给出的位置i,将其在链表中删除,并将删除的数据保存在变量e中

Status ListDelete_L(LinkList &L,int i,ElemType &e){ //将线性表L中第i个数据元素删除。通过e将删除的变量保存起来

LNode *p; //删除算法中i的合理取值范围是1~n。

p = L;

LNode *q;

int j = 0;

while(p->next && j<i-1){ //寻找第i-1个结点,并让p指向第i-1个结点。查找删除第1~n个位置的元素

p = p->next;

++j;

} //跳出循环后此时,p所指向的是第i-1个结点

if(!(p->next) || j>i-1) //删除位置不合理 。!(p->next)的意思是p的后继结点不存在。

return ERROR;

q = p->next; //注意//此时p->next指向的是第i个结点。q是临时保存被删除结点的地址,以备将其释放

p->next = q->next; //注意//也可以写成p->next = p->next->next; 即改变删除结点的前驱结点的指针域。

e = q->data; //保存删除结点的数据域

delete q; //释放删除结点的空间

return OK;

}

十三、头插法建立单链表,逆序插入,链表中正序存储

头插法:元素插入在链表头部。

void CreateList_Head(LinkList &L,int n){ //头插法建立单链表

L = new LNode;

L->next = NULL; //先建立一个带头结点的单链表

for(i=n;i>0;--i){

p = new LNode; //生成新结点p

scanf(&p->data); //输入元素值

p->next = L->next; 插入到头节点。一开始L->next指向为null,新结点指向null 。之后L->next指向上一个循环的旧结点p

L->next = p; 头结点指向新结点 ,之后指向新的结点p

}

}

十四、尾插法建立单链表,正序插入,链表中正序存储

尾插法:元素插入在链表尾部

void CreateList_R(LinkList &L,int n){ //尾插法。正位序输入n个元素的值,建立带表头节点的单链表L

L = new LNode;

L->next = NULL;

LNode *r;

r = L; //尾指针r指向头结点

for(i=0;i<n;++i){

p = new LNode; //生成新结点p

scanf(&p->data); //输入元素值

p->next = NULL;

r->next = p; //插入到表尾 ,将新结点放在尾结点的后面

r = p; //r指向新的尾结点 。新插入的结点就是现在新的尾结点了

}

}

#include<stdio.h>        //单链表的基本操作 
                        //此代码不可运行,含伪代码。 
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define INFEASIBLE    -1
#define OVERFLOW    -2
#define MAXSIZE 100
typedef int Status;

typedef struct{        //定义数据域 
    char num[8];
    char name[8];
    int score;
}ElemType; 

typedef struct LNode{
    ElemType    data;    //结点的数据域 
    struct Lnode *next;    //为指向下一个结点的指针域,并且所指向的也是Lnode型的数据 
}LNode,*LinkList;    //LinkList为指向结构体Lnode的指针类型,可定义链表L: LinkList p;等价于 LNode *p; 

Status InitList_L(LinkList &L){        
    L = new LNode;            //生成新结点作为头结点,用头指针L指向头结点 
//    L = (LinkList)malloc(sizeof(LNode));
    L->next = NULL;            //将头结点的指针域置空 
    return OK;
} 

int ListEmpty(LinkList L){        //若L为空表,则返回1,否则返回0 
    if(L->next)        //非空 
        return 0;
    else
        return 1;
}


Status DestroyList_L(LinkList &L){        //销毁单链表L 
    Lnode *p;
//    LinkList p;
    while(L){    //判断L指向的后一个结点是否为空 
        p = L;
        L = L->next;
        delete p;    //等同于free(p); 
    }
    return OK; 
} 


Status ClearList(LinkList &L){        //将L重置为空表 
    Lnode *p,*q;    //或 LinkList p,q;
    p = L->next;    //这指向的还只是头结点,并不是首元结点 
    while(p){        //判断下一结点是否为空 
        q = p->next;
        delete p;    //等同于free(p); 只是将p的内存给释放了 
        p = q;    
    }
    L->next = NULL;    //令头结点指针域为空 
    return OK; 
}

int ListLength_L(LinkList L){        //返回L中数据元素的个数 
    LinkList p;        //Lnode *p; 
    p = L->next;//L为头结点,L->next为L的指针域,所指向的为首元结点的地址。所以p指向的是第一个结点即首元结点。
    int i=0;
    while(p){        //遍历单链表,统计结点数 
        i++;
        p = p->next; //p指向下一结点 
    }
     return i;
} 

Status GetElem_L(LinkList L,int i,ElemType &e){    //取值。获取线性表L中的某个数据元素的内容,通过变量e返回
    p = L->next;    //初始化,让p指向首元结点 
    int j=1; 
    while(p && j<i){    //向后扫描,直到p指向的第i个元素 或 p为空 
        p = p->next;
        ++j;
    }
    if(!p || j>i)    //若第i个元素不存在 
        return ERROR;     
    e = p->data;    //取第i个元素
    return OK; 
}

Lnode *LocateElem_L(LinkList L,ElemType e){        //在线性表L中查找值为e的数据元素
                                                //若找到,则返回L中值为e的数据元素的地址,查找失败则返回NULL。 
    p = L->next;
    while(p && p->data!=e)    //p不为空,且没有找到e值 
        p = p->next;        //指向下一个 
    return p;
} 

int LocateElem_L1(LinkList L,ElemType e){        //在线性表L中查找值为e的数据元素的位置序号 
                                                //返回L中值为e的数据元素的位置序号 
    p = L->next;
    int j=1;        //从头开始计数 
    while(p && p->data!=e){
        p = p->next;
        j++;
    } 
    if(p)    //如果p值为空,则返回0,否则返回位置序号 
        return j;
    else
        return 0;
} 

Status ListInsert_L(LinkList &L,int i,ElemType e){    //插入。在L中第i个元素之前插入数据元素e 
                                                    //插入算法中i的合理取值范围是1~n+1。 
    p = L;                //此处p为头结点开始,以防有人要在第一个元素前插入数据元素e 
    int j = 0;
    while(p && j<i-1){        //寻找第i-1个结点。若退出循环,即j=i-1或者p为空。 
        p = p->next;
        ++j;
    } 
    if(!p || j>i-1)        //若i大于表长+1 或者小于1,则插入位置非法 
        return ERROR;
                        //这后面几步为关键步骤!!! 
    s = new LNode;        //先生成新结点s 
    s->data = e;        //再将结点s的数据域置为e 
    s->next = p->next;    //先将第i个结点,放在新结点的后面。即新结点指向第i个结点,作为新结点的后继。 
    p->next = s;        //再将新结点放在,第i-1个结点的后面。即第i-1个结点指向新结点,作为新结点的前驱。
    return OK; 
}     
 
Status ListDelete_L(LinkList &L,int i,ElemType &e){        //将线性表L中第i个数据元素删除。通过e将删除的变量保存起来 
    LNode *p;                                            //删除算法中i的合理取值范围是1~n。 
    p = L;
    LNode *q;
    int j = 0;
    while(p->next && j<i-1){    //寻找第i-1个结点,并让p指向第i-1个结点。查找删除第1~n个位置的元素 
        p = p->next;
        ++j;
    }                             //跳出循环后此时,p所指向的是第i-1个结点 
    if(!(p->next) || j>i-1)        //删除位置不合理 。!(p->next)的意思是p的后继结点不存在。 
        return ERROR;
    q = p->next;                //注意//此时p->next指向的是第i个结点。q是临时保存被删除结点的地址,以备将其释放 
    p->next = q->next;            //注意//也可以写成p->next =  p->next->next;     即改变删除结点的前驱结点的指针域。 
    e = q->data;                //保存删除结点的数据域 
    delete q;                    //释放删除结点的空间 
    return OK; 
} 

void CreateList_Head(LinkList &L,int n){    //头插法建立单链表 
    L = new LNode;
    L->next = NULL;                    //先建立一个带头结点的单链表 
    for(i=n;i>0;--i){
        p = new LNode;                //生成新结点p 
        scanf(&p->data);            //输入元素值
        p->next = L->next;            插入到头节点。一开始L->next指向为null,新结点指向null 
        L->next = p;                 头结点指向新结点 
    }
} 

void CreateList_R(LinkList &L,int n){    //尾插法。正位序输入n个元素的值,建立带表头节点的单链表L 
    L = new LNode;
    L->next = NULL;
    LNode *r; 
    r = L;        //尾指针r指向头结点
    for(i=0;i<n;++i){
        p = new LNode;                //生成新结点p 
        scanf(&p->data);            //输入元素值
        p->next = NULL;
        r->next = p;            //插入到表尾 ,将新结点放在尾结点的后面 
        r = p;                     //r指向新的尾结点 。新插入的结点就是现在新的尾结点了 
    } 
}

int main()
{
    
} 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/332960.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

物理师知识大杂烩|CT模拟机质量控制指南

引言 放射治疗 CT 模拟机&#xff08;computed tomography simulators, CT-Sim&#xff09;由带有平板床面的 CT 扫描仪、用于患者定位与体表标记的外部激光系统、CT 模拟软件以及各种硬拷贝输出设备组成。CT 模拟机为放射治疗计划设计提供了患者肿瘤、正常组织与危及器官的影…

TMDSEVM6657LS评估板恢复出厂默认状态

TMDSEVM6657LS评估板恢复出厂默认状态 前言 TMDSEVM6657LS评估板特别适用于DSP开发的初学者&#xff0c;但有时候拿到手的开发板几经流转&#xff0c;被别人修改过&#xff0c;也可能自己烧录过程出错&#xff0c;导致开发板的状态未知等原因&#xff0c;需要恢复到出厂默认状…

Django的安装及创建项目

Django的安装及创建demo项目 打开PyCharm&#xff0c;选择创建Django项目勾选使用Virtualenv创建虚拟环境&#xff0c;并选择合适的Python编译器版本即可。 注&#xff1a;如果因为其他原因&#xff08;没有关闭vpn等&#xff09;也可以在PyCharm提供的terminal终端&#xf…

uni-app低成本封装一个取色器组件

在uni-ui中找不到对应的工具 后面想想也是 移动端取色干什么&#xff1f; 没办法 也挂不住特殊需求 因为去应用市场下载 这总东西 又不是很有必要 那么 下面这个组件或许能解决您的烦恼 <template><view class"content"><view class"dialog&…

侯捷C++系统工程师

前言我相信对于每一个学习C的同学和从业者来说&#xff0c;台湾著名学者侯捷老师的C系列都是不可错过的好视频。侯捷老师在网上已有五门课&#xff0c;分别是&#xff1a;C面向对象开发、STL标准库与泛型编程、C新标准C1&14、C内存管理机制以及C Startup揭秘讲师介绍侯捷老…

python基于django+vue的高铁地铁火车订票管理系统

目录 1 绪论 1 1.1课题背景 1 1.2课题研究现状 1 1.3初步设计方法与实施方案 2 1.4本文研究内容 2 2 系统开发环境 4 2.1 使用工具简介 4 2.2 环境配置 4 2.4 MySQL数据库 5 2.5 框架介绍 5 3 系统分析 6 3.1系统可行性分析 6 3.1.1经济可行性 6 3.1.2技术可行性 6 3.1.3运行可…

pandas——DataFrame基本操作(二)【建议收藏】

pandas——DataFrame基本操作&#xff08;二&#xff09; 文章目录pandas——DataFrame基本操作&#xff08;二&#xff09;一、实验目的二、实验原理三、实验环境四、实验内容五、实验步骤1.修改数据2.缺失值3.合并1.concat合并2.使用append方法合并3.使用merge进行合并4.使用…

为什么实时ERP系统是唯一的出路?

长期以来&#xff0c;企业主不得不等待数天&#xff0c;有时甚至数周&#xff0c;才能获得财务和运营结果。今天&#xff0c;尤其是在我们可以使用高速计算机和实时技术的情况下&#xff0c;这绝不应该成为可接受的标准。 然而&#xff0c;太多的大牌ERP系统仍然使用批量处理…

2023年网络安全比赛--Web综合渗透测试中职组(超详细)

一、竞赛时间 180分钟 共计3小时 二、竞赛阶段 1.通过URL访问http://靶机IP/1,对该页面进行渗透测试,将完成后返回的结果内容作为FLAG值提交; 2.通过URL访问http://靶机IP/2,对该页面进行渗透测试,将完成后返回的结果内容作为FLAG值提交; 3.通过URL访问http://靶机IP/3,对…

CDN绕过技术总汇

注 本文首发于合天网安实验室 首发链接&#xff1a;https://mp.weixin.qq.com/s/9oeUpFUZ_0FUu6YAhQGuAg 近日HVV培训以及面试&#xff0c;有人问了CDN该如何绕过找到目标真实IP&#xff0c;这向来是个老生常谈的问题&#xff0c;而且网上大多都有&#xff0c;但是有些不够全面…

中国网站安全形式风险报告

声明 本文是学习2017中国网站安全形势分析报告. 而整理的学习笔记,分享出来希望更多人受益,如果存在侵权请及时联系我们 网站漏洞检测分析 网站漏洞的整体形势可以从两个角度分析&#xff1a;一是网站安全检测的自动扫描结果统计&#xff0c;二是网站被报告漏洞情况的统计。…

FreeRTOS队列 | FreeRTOS九

目录 说明&#xff1a; 一、队列简介 1.1、什么是队列 1.2、队列的优势 1.3、队列实现功能 1.4、队列使用了解 1.5、队列特点 1.6、队列阻塞处理 1.7、队列出队入队过程 二、队列结构体 2.1、结构体了解 2.2、共同体了解 2.3、队列结构体存储区 三、队列API函数 …

nacos配置中心搭建

网站每次更新版本都有短暂暂停&#xff0c;影响用户使用&#xff0c;返回经常不可用&#xff0c;需要改进 需要实现高可用&#xff0c;搭建负载均衡&#xff0c;实现jenkinsnacos不停机部署 nacos搭建预备环境准备 64 bit OS&#xff0c;支持 Linux/Unix/Mac/Windows&#x…

vue2.0项目第一部分

论坛项目后端管理系统服务器地址&#xff1a;http://172.16.11.18:9090swagger地址&#xff1a;http://172.16.11.18:9090/doc.html前端h5地址&#xff1a;http://172.16.11.18:9099/h5/#/前端管理系统地址&#xff1a;http://172.16.11.18:9099/admin/#/搭建项目vue create . …

JavaScript 变量提升

文章目录JavaScript 变量提升JavaScript 初始化不会提升在头部声明你的变量JavaScript 变量提升 JavaScript 中&#xff0c;函数及变量的声明都将被提升到函数的最顶部。 JavaScript 中&#xff0c;变量可以在使用后声明&#xff0c;也就是变量可以先使用再声明。 以下两个实…

前端面试题汇总

一&#xff1a;JavaScript 1、闭包是什么&#xff1f;利弊&#xff1f;如何解决弊端&#xff1f; 闭包是什么&#xff1a;JS中内层函数可以访问外层函数的变量&#xff0c;外层函数无法操作内存函数的变量的特性。我们把这个特性称作闭包。 闭包的好处&#xff1a; 隔离作用…

三、Linux文件 - Close函数讲解实战,文件权限

目录 1.Close函数 2.Linux文件权限 3.项目实战 3.1Close 项目实战1 3.2 文件权限项目实战 -Open函数设置权限 1.Close函数 参数说明 在Linux系统库的定义&#xff1a; int close(int fd) 包含的头文件 #include <unistd.h> 功能就是简单的关闭文件 注&#x…

荧光素标记PEG衍生物Fluorescein-PEG-Acid,FITC-PEG-COOH

英文名称&#xff1a;FITC-PEG-COOH&#xff0c;Fluorescein-PEG-Acid 中文名称&#xff1a;荧光素-聚乙二醇-羧基 荧光素标记的聚乙二醇PEG衍生物的荧光波长为495 nm&#xff0c;发射大约515 ~ 520 nm处有最大吸收。FITC组可以很容易地从它的黄色和绿色荧光。额外的功能&…

Python算法:深度优先搜索—DFS(模板及其样例)

深度优先搜索搜索 【介绍】 • 沿着一条路径一直搜索下去&#xff0c;在无法搜索时&#xff0c;回退到刚刚访问过的节点。 • 并且每个节点只能访问一次。 • 本质上是持续搜索&#xff0c;遍历了所有可能的情况&#xff0c;必然能得到解。 • 流程是一个树的形式&#xff0c;…

深度学习基础-机器学习基本原理

本文大部分内容参考《深度学习》书籍&#xff0c;从中抽取重要的知识点&#xff0c;并对部分概念和原理加以自己的总结&#xff0c;适合当作原书的补充资料阅读&#xff0c;也可当作快速阅览机器学习原理基础知识的参考资料。 前言 深度学习是机器学习的一个特定分支。我们要想…