单链表的简单操作与演示

单链表

单链表概念和简单的设计

单链表是一种链式存取的数据结构,链表中的数据是以结点来表示的,每个结点由元素和指针构成。

元素表示数据元素的映象,就是存储数据的存储单元;指针指示出后继元素存储位置,就是连接每个结点的地址数据。

以结点的序列表示的线性表称作线性链表,也就是单链表,单链表是链式存取的结构。

对于链表的每一个结点,我们使用结构体进行设计,其主要内容有:

其中,DATA数据元素,可以为你想要储存的任何数据格式,可以是数组,可以是int,甚至可以是结构体(这就是传说中的结构体套结构体)

NEXT为一个指针,其代表了一个可以指向的区域,通常是用来指向下一个结点,链表的尾部NEXT指向NULL(空),因为尾部没有任何可以指向的空间了

故,对于一个单链表的结点定义,可以代码描述成:

//定义结点类型typedefstructNode {int data; //数据类型,你可以把int型的data换成任意数据类型,包括结构体struct等复合类型structNode *next;//单链表的指针域} Node,*LinkedList; //Node表示结点的类型,LinkedList表示指向Node结点类型的指针类型

链表的初始化

初始化主要完成以下工作:创建一个单链表的前置节点并向后逐步添加节点,一般指的是申请结点的空间,同时对一个结点赋空值(NULL),其代码可以表示为:

LinkedList listinit(){Node L; L=(Node)malloc(sizeof(Node)); //开辟空间 if(L==NULL){ //判断是否开辟空间失败,这一步很有必要printf(“申请空间失败”);//exit(0); //开辟空间失败可以考虑直接结束程序 } L->next=NULL; //指针指向空}

注意:一定要判断是否开辟空间失败,否则生产中由于未知的情况造成空间开辟失败,仍然在继续执行代码,后果将不堪设想啦,因此养成这样的判断是很有必要的。

头插入法创建单链表

利用指针指向下一个结点元素的方式进行逐个创建,使用头插入法最终得到的结果是逆序的。如图所示:

从一个空表开始,生成新结点,并将读取到的数据存放到新结点的数据域中,然后将新结点插入到当前链表的表头,即头结点之后。

//头插法建立单链表LinkedList LinkedListCreatH(){Node *L; L = (Node *)malloc(sizeof(Node)); //申请头结点空间 L->next = NULL; //初始化一个空链表int x; //x为链表数据域中的数据while(scanf(“%d”,&x) != EOF) { Node *p; p = (Node *)malloc(sizeof(Node)); //申请新的结点 p->data = x; //结点数据域赋值 p->next = L->next; /将结点插入到表头L–>|2|–>|1|–>NULL L->next = p; }return L;}

插入法创建单链表

如图所示为尾插入法的创建过程。

头插法生成的链表中,结点的次序和输入数据的顺序不一致。若希望两者次序一致,则需要尾插法。

该方法是将新结点逐个插入到当前链表的表尾上,为此必须增加一个尾指针r, 使其始终指向当前链表的尾结点,代码如下:

//尾插法建立单链表LinkedList LinkedListCreatT(){Node *L; L = (Node *)malloc(sizeof(Node)); //申请头结点空间 L->next = NULL; //初始化一个空链表 Node *r; r = L; //r始终指向终端结点,开始时指向头结点int x; //x为链表数据域中的数据while(scanf(“%d”,&x) != EOF) { Node *p; p = (Node *)malloc(sizeof(Node)); //申请新的结点 p->data = x; //结点数据域赋值 r->next = p; //将结点插入到表头L–>|1|–>|2|–>NULL r = p; } r->next = NULL;return L;}

遍历单链表如打印、修改

从链表的头开始,逐步向后进行每一个元素的访问,称为遍历。

对于遍历操作,我们可以衍生出很多常用的数据操作,比如查询元素,修改元素,获取元素个数,打印整个链表数据等等。

进行遍历的思路极其简单,只需要建立一个指向链表L的结点,然后沿着链表L逐个向后搜索即可,代码如下:

//便利输出单链表void printList(LinkedList L){Node *p=L->next;int i=0;while§{printf(“第%d个元素的值为:%d\n”,++i,p->data); p=p->next; }}

对于元素修改操作,以下是代码实现:

//链表内容的修改,在链表中修改值为x的元素变为为k。LinkedList LinkedListReplace(LinkedList L,int x,int k){Node *p=L->next;int i=0;while§{if(p->data==x){ p->data=k; } p=p->next; }return L;}

简单的遍历设计的函数只需要void无参即可,而当涉及到元素操作时,可以设计一个LinkedList类型的函数,使其返回一个操作后的新链表。

插入操作

链表的插入操作主要分为查找到第i个位置,将该位置的next指针修改为指向我们新插入的结点,而新插入的结点next指针指向我们i+1个位置的结点。

其操作方式可以设置一个前驱结点,利用循环找到第i个位置,再进行插入。

如图,在DATA1和DATA2数据结点之中插入一个NEW_DATA数据结点:

从原来的链表状态:

到新的链表状态:

代码实现如下:

//单链表的插入,在链表的第i个位置插入x的元素LinkedList LinkedListInsert(LinkedList L,int i,int x){Node *pre; //pre为前驱结点 pre = L;int tempi = 0;for (tempi = 1; tempi < i; tempi++) { pre = pre->next; //查找第i个位置的前驱结点 } Node *p; //插入的结点为p p = (Node *)malloc(sizeof(Node)); p->data = x; p->next = pre->next; pre->next = p;return L;}
删除操作

删除元素要建立一个前驱结点和一个当前结点,当找到了我们需要删除的数据时,直接使用前驱结点跳过要删除的结点指向要删除结点的后一个结点,再将原有的结点通过free函数释放掉。如图所示:

代码如下:

//单链表的删除,在链表中删除值为x的元素LinkedList LinkedListDelete(LinkedList L,int x) {Node *p,*pre; //pre为前驱结点,p为查找的结点。 p = L->next;while(p->data != x) { //查找值为x的元素 pre = p; p = p->next; } pre->next = p->next; //删除操作,将其前驱next指向其后继。 free§;return L;}

基本操作代码

package com.ma.linked;public class DLLinkedList {//定义一个头节点private GoodsNode head = new GoodsNode(0,"",0);//往链表中添加结点public void add(GoodsNode node){GoodsNode temp = head;while (true){if(temp.next == null){break;}temp = temp.next;}temp.next = node;}//根据商品的id值进行添加,从小到大依次排序public void addOrder(GoodsNode node){GoodsNode temp = head;boolean flag = false;while (true){if(temp.next == null){break;}if (temp.next.id >node.id ){break;}else if (temp.next.id == node.id){flag = true;break;}temp = temp.next;}if (flag){System.out.println("已经存在了此商品,请勿重复添加");}else {node.next = temp.next;temp.next = node;}}/** 修改结点* 1.先找到链表中目标结点* 2.根据新数据进行修改* 3.根据商品编号进行查找* */public void updateNode(GoodsNode node){//如果链表为空if (head.next == null){System.out.println("链表为空");return;}GoodsNode temp = head.next;boolean flag = false;while (true){if (temp == null){break;}if (temp.id == node.id){flag = true;break;}temp = temp.next;}if (flag){//真正的修改结点temp.name = node.name;temp.price = node.price;}else {System.out.println("你要修改的结点在链表中未找到");}}//结点删除功能public void delNode(int id){GoodsNode temp = head;boolean flag = false;while (true){if (temp.next == null){break;}if (temp.next.id == id){flag = true;break;}temp =  temp.next;}if (flag){temp.next = temp.next.next;}else {System.out.println("没有找到要删除的结点" );}}//查看链表中每一个结点元素public void list(){if (head.next == null){return;}GoodsNode temp = head.next;while (true){if (temp ==  null){break;}System.out.println(temp);temp = temp.next;}}}
package com.ma.linked;public class GoodsNode {public int id;public String name;public double price;public GoodsNode next;public GoodsNode(int id, String name, double price) {this.id = id;this.name = name;this.price = price;}@Overridepublic String toString() {return "GoodsNode{" +"id=" + id +", name='" + name + '\'' +", price=" + price +'}';}
}

演示代码

package com.ma.linked;public class LinkedTest {public static void main(String[] args) {GoodsNode goodsNode1 = new GoodsNode(1,"耐克鞋子",999.9);GoodsNode goodsNode2 = new GoodsNode(2,"阿迪鞋子",777.9);GoodsNode goodsNode3 = new GoodsNode(3,"李宁鞋子",555.9);GoodsNode goodsNode4 = new GoodsNode(4,"安踏鞋子",222.9);DLLinkedList dlLinkedList = new DLLinkedList();
//        dlLinkedList.add(goodsNode1);
//        dlLinkedList.add(goodsNode2);
//        dlLinkedList.add(goodsNode3);
//        dlLinkedList.add(goodsNode4);dlLinkedList.addOrder(goodsNode2);dlLinkedList.addOrder(goodsNode4);dlLinkedList.addOrder(goodsNode1);dlLinkedList.addOrder(goodsNode3);dlLinkedList.add(new GoodsNode(8,"特步鞋子",333.9));dlLinkedList.addOrder(new GoodsNode(5,"鸿星尔克鞋子",111.9));dlLinkedList.updateNode(new GoodsNode(8,"特步鞋子",444.9));dlLinkedList.delNode(8);dlLinkedList.list();}
}

);

    dlLinkedList.add(new GoodsNode(8,"特步鞋子",333.9));dlLinkedList.addOrder(new GoodsNode(5,"鸿星尔克鞋子",111.9));dlLinkedList.updateNode(new GoodsNode(8,"特步鞋子",444.9));dlLinkedList.delNode(8);dlLinkedList.list();}

}


单链表的简单操作与演示相关推荐

  1. java 结构体_Java实现单链表的简单操作

    文章目录 前言 一.基本实现思路 二.代码实现 1.定义结点类2.定义链表类3.测试调用4.结果 总结 前言 用Java实现单链表的简单操作,阅读本文和上一篇文章体会Java中类与C++中结构体指针的 ...

  2. 数据结构(单链表的相关操作)

    为什么80%的码农都做不了架构师?>>>    #include <stdio.h> #include <stdlib.h> #define ElemType ...

  3. 单链表的实现操作(C语言)

    //单链表的实现操作 #include <stdio.h> #include <malloc.h> #include <stdlib.h> //数据类型定义 typ ...

  4. SWUSTOJ #953 单链表的删除操作的实现

    SWUSTOJ #953 单链表的删除操作的实现 题目 输入 输出 样例输入 样例输出 源代码 题目 建立长度为 n 的单链表,删除第 i 个结点之前的结点. 输入 第一行为自然数 n,表示链式线性表 ...

  5. 2015年数据结构第四题(带头结点单链表的简单选择排序)(C/C++)

    题目: 算法思想:每次从单链表的待排序部分中找到最小的元素所在的节点,再和与头节点直接相连的单链表的已排序部分的下一个结点通过调整指针的方式交换位置,重复多次即可. 代码实现: #include< ...

  6. 西南科技大学OJ题 单链表的删除操作的实现0953

    单链表的删除操作的实现 1000(ms) 65535(kb) 2896 / 13622 建立长度为n的单链表,删除第i个结点之前的结点. 输入 第一行为自然数n,表示链式线性表的长度: 第二行为n个自 ...

  7. 单链表实现简单选择排序

    目录 算法思想 代码实现 头插法递增 头插法递减 尾插法递增 尾插法递减 完整程序测试 测试结果 算法思想 我们用不带头结点的单链表实现简单选择排序. 递增:每次从原链表中找出一个最大(最小)元素,然 ...

  8. [数据结构与算法] 单链表的简单demo

    Vc6之下编译通过.. 1 /******************************************************* 2 * @: Project: 单链表数据结构演示 3 * ...

  9. 单链表的插入操作(全)

    1 在指定位序插入数据 第一步   主要执行操作:查找  先查找所要插入位置的前一个元素  具体方法:根据链表的特点-每一个节点都需要一个数据域和指针域  所以只需从头节点遍历到所要插入数据的的前一个 ...

最新文章

  1. Fuzzy Hashing 算法工具ssdeep 使用
  2. k8s traefik ingress tls
  3. boost::sort模块spreadsort 完全排序的数据示例
  4. 阿里P8大佬亲自讲解!朝阳java培训
  5. 【离散数学】图的基本概念和结论
  6. (篇二)C语言动态分配内存、计算π的值
  7. Ubuntu下打开windows的txt文件乱码解决
  8. 2021最新Node.js视频教程(基础+全栈项目)
  9. (20190401)IGS GNSS数据下载网址与下载说明
  10. 转载:技术文化和惨淡命运 —— 怀念中国雅虎
  11. 弱小目标检测领域下图像的信噪比(SNR)计算方法
  12. 【大话设计模式】模式二 :工厂模式
  13. t-SNE算法解析与简单代码实现
  14. python 实现复制文件夹以及文件夹下的子文件
  15. 关于写论文的一些想法——如何写好一篇论文
  16. linux抓取vlan数据包,如何抓取 带VLAN tag的包
  17. 批处理命令--call和start
  18. 【JavaWeb】JSP:基本语法大全
  19. vue项目实现大屏展示 自适应问题
  20. word2013插入excel对象报错_excel插入对象文件夹 Excel2013中插入对象文件的方法

热门文章

  1. 陪着时光,走过羊肠阡陌
  2. 2021年全球与中国水上巡航行业市场规模及发展前景分析
  3. Ubuntu 19.04初体验
  4. 双胺基修饰MOF/GO烯复合材料|硫修饰Cu基MOF材料|磁性纳米多孔碳材料FeO@C|mof材料的复杂定制
  5. EXCEL 子母饼图
  6. [转]scite文本编辑器的说明
  7. 【数据科学】使用Python建立你的数据处理肌肉记忆
  8. 之和质数c语言题判断,C语言经典例题100例——C语言练习实例33解答(质数判断)...
  9. STM32F4应用-GPIO
  10. 塑造棋牌游戏文化内涵