学会了单链表的基本操作之后,我们就可以自定义一些非常有意思的功能了,例如对单链表中的元素进行排序,(排序规则可以由自己定),将链表翻转等等,这里主要是讲老师布置的几个问题,我觉得也非常有趣,大家也可以思考一下,由于这些方法几天前就写完了,五一假在家中也没有对之前的链表进行更多的修改了,所以还是用之前所写过的单链表结构继续添加功能吧。
在实现所有功能之前先来个前言,接下来的这两个方法对后面的每一步都是至关重要的,第一个是获取链表长度的方法:
获取链表长度的方法其实可以是打印链表方法的翻版,我最开始的时候也是这样做的,不过后来发现了一个更好的更不容易出错的方法,在链表类中定义一个size属性
int size=0;
然后在所有的对链表有长度修改的方法中都对size进行一次修改,例如添加元素的方法最后加一句size++,删除元素的方法最后加一句size--等等(当然size不能小于0)。
这样获取size的方法中只需要一句话就可以解决了:
int size(){
return size;
}
另外一个就是获取指定位置结点元素的方法,如下:
/** * 查找指定位置结点元素的方法 */ public Node get(int index){ Node node=head; int j=1; //找到第index while(node!=null&&j<index){ node=node.next; j++; } return node; }
下面在具体问题中来看一下这两个方法的应用吧。
1.对链表中的元素进行排序(如果链表中的元素是整数的话)
相信看完前两个方法之后,排序的方法已然在心中出现了,如果这不是一个单链表而是一个数组的话,对数组进行排序相信大家都不会陌生了,所以这里也只是用到了最简单的冒泡排序思想而已:
/** * 如果链表中的元素是整型元素,则排列链表 */ public void sort(){ Object obj=null; Node temp=new Node(obj);//媒介结点 for(int i=0;i<=size();i++){ for(int j=i+1;j<=size();j++){ //冒泡排序思想,交换数据域 if(Integer.parseInt((String)get(i).obj)>Integer.parseInt((String)get(j).obj)){ temp.obj=get(i).obj; get(i).obj=get(j).obj; get(j).obj=temp.obj; } } } }
2.将链表中的元素封装到一个数组当中
看到这里大家可能会觉得奇怪,为什么这个方法不写在上面,第一个方法不就是利用了这个思想么?其实只是因为我是在做完第一个题目之后才想到的这个方法,所以放在之后讲,我想这正跟我们的学习过程一样,很多简单的方法是在做了复杂的方法之后才想出来的:
/** * 将链表封装成一个对象数组 */ public Object[] toArray(){ //创建 Object obj[]=new Object[size()]; Node node=head; int j=0; while(node!=null&&j<obj.length){ obj[j++]=node.obj; node=node.next; } return obj; }
3. 将链表翻转
最开始看到这个题目的时候,我还在反复推敲,如何把链表的引用域与数据域对调过来,因为这样就可以实现链表的翻转的工作,在那折腾了半个小时之后才发现,是我2B了,要实现链表翻转其实就像链表排序一样,只要交换数据域就行了,方法如下:
/** * 翻转链表的方法 */ public void turn(){ int j=size(); //获取最后一个下标位置 //将前一半与后一半的位置交换 Object temp; for(int i=1;i<=size()/2;i++){ temp=get(i).obj; get(i).obj=get(j).obj; get(j).obj=temp; j--; } }
4.如果该单链表具有环,怎么样找到环的入口位置?
这里采用的是穷尽搜索的方法,当然你还可以用效率更高的二分搜索法,不过我想不管是哪个方法,在搜索之前先判断要不要搜索都比搜索本身来的快一点,如何判断一个链表是否有环呢?很简单,当last结点的next域为空时链表不就没有环了么,方法如下:
/** * 搜索环链表环的位置的入口 */ public void searchHoop(){ Node node=head; int location=1; //环的入口位置 while(node!=null&&location<=size()){ node=node.next;//寻找下一个结点 if(last.next==null){ System.out.println("该链表没有环"); break; } //如果最后一个结点的引用指向了之中的某一个结点 else if(last.next==node&&location<=size()){ System.out.println("环的入口位置为第"+location+"个结点"); break; } location++; } }
方法实现方面就先讲到这了,不过由于之前的发的那篇关于单向链表的实现上,语法结构其实并不严谨,后面几个方法在使用起来可能需要稍做揣摩,此外,也希望大家一起来探讨一下更多有趣的方法。
相关推荐
玩转单链表——文章中所讲述的程序源代码
单链表是一种基础的数据结构,它在计算机科学中扮演着重要的角色,特别是在处理动态数据集合时。单链表由一系列节点组成,每个节点包含两部分:数据域和指针域。数据域存储实际的元素值,而指针域则指向链表中的下一...
本文将详细阐述如何使用C++来实现单链表的基本操作,包括创建、遍历、插入、删除、判断空、计算长度以及查找节点。 首先,我们从创建单链表开始。单链表是由一系列节点组成的数据结构,每个节点包含一个数据元素和...
c#做的单链表,单链表,有一些东西不是特别好,看看吧
实验二 单链表实验 一、实验目的 1、掌握用Visual C++6.0上机调试单链表的基本方法 2、掌握单链表的插入、删除、查找、求表长以及有序单链表的合并算法的实现 二、实现内容 1、单链表基本操作的实现 在带头结点的...
建立一个单链表,实现单链表的初始化,插入、删除节点等功能,以及确定某一元素在单链表中的位置。 (1) 初始化单链表; (2) 依次采用尾插入法插入a,b,c,d,e元素; (3) 输出单链表L; (4) 输出单链表L的长度...
"关于有序单链表的详细设计" 本资源旨在设计和实现一个有序单链表,涵盖了需求分析、概要设计、详细设计、调试分析和测试结果等方面。下面是对该资源的知识点解析: 一、需求分析 1. 有序单链表的元素类型限定为 ...
合并单链表(C源代码)合并单链表(C源代码)合并单链表(C源代码)合并单链表(C源代码)合并单链表(C源代码)合并单链表(C源代码)合并单链表(C源代码)合并单链表(C源代码)合并单链表(C源代码)合并单链表(C源代码)合并单链表...
1、从键盘上依次输入21、18、30、75、42、56,逆序创建单链表,并输出单链表中的各元素值。 2、分别在单链表的第3个位置和第9个位置插入67和10,给出插入成功或失败的信息,并输出单链表中的各元素值。 3、删除...
单链表解决约瑟夫环问题
### 数据结构之单链表实例解析 在计算机科学领域中,数据结构是研究如何组织、管理数据的关键技术之一。单链表作为一种基本的数据结构,在实际应用中极为常见。本文将通过对给定代码片段的分析,深入理解单链表的...
单链表是一种常见的数据结构,具有高效的数据插入和删除能力,尤其在处理大量数据时能够节省内存。在C语言中实现单链表通常涉及以下几个步骤:定义数据结构、初始化链表、添加节点、删除节点、获取链表长度、获取...
代码中包含单链表的常用操作,主要实现以下六个算法: 1.单链表的就地反转 2.链表相交或求公共起始节点 3.求链表倒数第n个节点 4.删除单个节点 5.判断链表是否有环 6.将2个递增的链表合并为递减链表 并全部调试通过...
(2)验证单链表及其基本操作的实现; (3)进一步理解算法与程序的关系,能够将单链表算法转换为对应的程序。 1.2 实验要求: (1)用头插法(或尾插法)建立带头结点的单链表; (2)对已建立的单链表实现插入、...
单链表的简单实现代码
建立一个单链表,在单链表上实现插入、删除和查找等操作,有菜单。 ⑴初始化字符型单链表H; ⑵采用尾插法建立单链表H,如(a,b,c,d,c); ⑶输出单链表H的长度; ⑷输出单链表H的第i个元素,如输出单链表H的第3...
单链表的就地反转 单链表的就地反转是指在不使用额外的存储空间的情况下,反转单链表的节点顺序。该操作对链表的结构进行了重新组织,使得链表的节点顺序被反转。 在该实验报告中,我们将学习如何使用C语言来实现...
单链表是一种常见的数据结构,它由一系列节点组成,每个节点包含数据和指向下一个节点的指针。在C++中,我们通常通过定义一个结构体或类来表示链表节点。在这个例子中,我们有一个名为`linkb`的结构体,它有两个成员...