`
尘大大
  • 浏览: 10888 次
  • 性别: Icon_minigender_2
最近访客 更多访客>>
文章分类
社区版块
存档分类
最新评论

链表的使用

 
阅读更多

链表主要分为单向链表、双向链表、循环链表
双向链表、循环链表都可以认为是单向链表的扩展,单向链表最基础,笔者的介绍也将基于单向列表
单向链表是一个在物理存储上不相邻的序列(与数组不同),它由结点组成,每个结点分为指针域和值域,值域发挥与数组元素类似的存储数值的作用,而指针域存储下一个结点的地址,结点与结点之间通过指针相连。
下图是单向链表的逻辑结构

可见只要得到第一个元素(通常称为头结点)即可通过指针获取整个链表的元素。
定义一个结点类
public class Node {
         //值域,定义为Object,能够存储任意类型的值
Object obj;
//指针域
         Node next;
public  Node(Object obj){
this.obj=obj;
}
}
定义一个链表类
public class LinkedList{
       //指向第一个元素的头结点
      Node head=null;
       //指向最后一个元素的尾结点
      Node last=head;
}
以下代码均为LinkedList类中的方法
添加元素
public void add(Object obj){
Node node=new Node(obj);
                 //将每个结点添加到尾结点后面,如果链表尚未添加任何元素
                    //则将要添加的结点赋给头结点,之后让last指向最后一个结点
if(head!=null){
last.next=node;
}else{
head=node;
}
last=node;


}
获取链表的元素个数
public int size(){
int count=0;
Node node=head;
while(node!=null){
count++;
node=node.next;
}

return count;
}
获取指定位置的元素
public Node get(int index){
int count=0;
Node node=head;
while(node!=null){
if(index==count){
return node;
}else{
node=node.next;
count++;
}
}
return null;
}
给链表排序的方法
public void sort(int sequence){
Node p,q,r;
//sequence判断按升序还是降序排列,此处为升序
if(sequence==0){
for(int i=size();i>1;i--){

for(int j=0;j<i-1;j++){
if(Integer.parseInt(get(j).obj.toString())>Integer.parseInt(get(j+1).obj.toString())){
//如果相邻的两个结点,前一个结点(赋给q)的值大于后一个结点(赋给r),则将他们的结点交换
q=get(j);r=get(j+1);
//让q的指针指向r的下一个元素
q.next=r.next;
//让r的指针指向q
r.next=q;
//让指向q的元素指向r
if(j!=0){
get(j-1).next=r;
}
//如果q为第一个元素,则交换后的r为第一个元素,将其赋给头结点
if(j==0){
head=r;
}
if(q.next==null){
last=q;
           }
}
}
}
}
//此方法仅考虑了按升序排列的情况,如果按降序排列,仅需将判断语句if()中的>改为<
}
让链表转置的方法
public void reverse(){
Node node_temp;
//让后一个结点的指针指向前一个结点
for(int i=size()-2;i>=0;i--){
get(i+1).next=get(i);
}
//原本的头结点此时为最后一个元素,即尾结点
head.next=null;
node_temp=head;
//原本的尾结点此时为头结点
head=last;
last=node_temp;
}
}
判断链表是否有环的方法
/**如果链表中的尾结点的指针并不为空,而是指向某个结点(包括它本身),则认为此链表有环*/
public static boolean isCircle(Node head){
Node n1,n2;
n1=n2=head;
/**两个元素n1、n2从头结点开始读取整个链表
  * 一个按顺序读,另一个间隔一个元素读,如果链表有环
  * 则一定会有n1=n2的情况
  */
while(n1!=null&&n2!=null){
try{
n1=n1.next;
n2=n2.next.next;
if(n1.equals(n2)){
return true;
}
}catch(NullPointerException e){
//如果n1 n2某次读到了空值,则该链表一定无环
return false;
}
}
return false;

}
以上代码存在一定缺陷
譬如调用get(int index)须每次从头结点开始读取,在排序方法中多次使用get(int index)方法可能造成时间的浪费。
  • 描述: 单向链表的逻辑结构图
  • 大小: 16.4 KB
分享到:
评论

相关推荐

    C语言 链表使用示例

    本教程将通过两个经典示例深入讲解如何在C语言中使用链表。 首先,我们来看第一个示例——"Demo1.c"。在这个示例中,我们将创建一个表示学生成绩的链表,每个节点包含学生的ID和分数。为了实现这个链表,我们需要...

    c++链表使用教程

    总结来说,这个C++链表教程涵盖了链表的基本概念、数据结构定义、操作符重载以及常见的链表操作函数实现,这些都是理解和使用链表的关键知识。通过这些内容,开发者可以有效地在C++中构建和管理链表数据结构,进行...

    双向链表使用说明.txt

    双向链表使用说明.txt

    使用 python3 实现一个链表

    使用 python3 实现一个链表 使用 python3 实现一个链表 使用 python3 实现一个链表 使用 python3 实现一个链表 使用 python3 实现一个链表 使用 python3 实现一个链表 使用 python3 实现一个链表 使用 python3 实现...

    数据结构_链表使用的例子程序

    数据结构学习辅助,链表使用例程,注释非常清楚,而且可以实际运行,方便初学者调试、体会

    linux内核链表提取与使用

    将linux内核源码中list.h拿出来, 增删与遍历部分写了详细注释, 关于链表合并, 没用过所以没写. 源码版本是2.6.32, 不过链表的源码改动应该不是很大. 我的邮箱2253238252@qq.com, 代码有什么不对的欢迎发邮件给我

    双向循环链表使用实例.doc

    在本文中,我们将深入探讨如何使用C++实现双向循环链表。双向循环链表是一种特殊的数据结构,每个节点不仅包含数据,还包含两个指针,分别指向前一个节点和后一个节点,形成一个首尾相接的循环链。这种数据结构在...

    集合(链表和数组的区别) 数组和链表.pdf

    链表使用引用来定位元素,时间复杂度为O(n)。这也就是为什么数组的访问速度比链表快的原因。 5. 插入和删除操作 数组插入或删除元素的时间复杂度为O(n),因为需要移动所有元素的位置。链表插入或删除元素的时间...

    python的链表与数组对比,优势和劣势 数组和链表.pdf

    链表使用指针来指向下一个节点,这可以导致指针的使用不当。 ### 实现的复杂性 链表的实现可以很复杂,需要考虑节点的管理、内存的分配等问题。 数组与链表的对比 ------------------- 数组和链表是两种常用的...

    c++链表学习实例--图书管理

    3. 节点号排序:这通常涉及到对链表的遍历,可以使用各种排序算法,如冒泡排序、选择排序或更高效的快速排序、归并排序等。在这个实例中,可能根据图书的编号进行排序。 4. 节点搜索:查找链表中特定值的节点,通常...

    linux内核链表介绍与了解

    这些扩展都是基于基础的`list`结构,增加了链表使用的灵活性和效率。 在实际应用中,比如在网络过滤框架Netfilter中,使用链表来组织协议族的`nf_sockopt_ops`结构,每个结构都有一个`struct list_head list`成员,...

    数据结构——链表——多项式加减

    - **链表的动态内存管理**:链表使用`malloc`动态分配内存,当链表不再需要时,应使用`free`释放已分配的内存,防止内存泄漏。 - **异常处理**:在实际编程中,应添加输入验证和错误处理机制,确保输入的有效性和...

    人工智能-项目实践-信息管理系统-学生信息管理系统之链表的使用

    在实际开发中,为了提高效率,可以考虑使用哈希表或二叉搜索树等数据结构配合链表使用。例如,可以建立一个哈希表,键为学号,值为指向链表中对应节点的指针,这样可以在常数时间内完成查找和删除操作。 链表在人工...

    c静态链表和动态链表

    动态链表使用完毕后,需要释放每个节点占用的内存空间,避免内存泄漏。 ```c void freeList(struct Car *head) { struct Car *p = head; while (p != NULL) { struct Car *temp = p; p = p-&gt;next; free...

    数组和链表的使用场景 数组和链表.pdf

    数组和链表的使用场景 在计算机科学中,数组和链表是两种基本的数据结构,它们都是线性表的实现方式,但它们有着不同的存储结构和访问方式,从而导致不同的使用场景。 数组是一种连续存储的数据结构,即在内存中...

    使用程序设计建立链表信息管理

    在这个课程设计中,我们将探讨如何使用链表来实现信息管理,包括增加、删除和显示链表中的节点。 链表的基本概念: 链表不同于数组,它不是在内存中连续分配空间,而是由一系列分散的节点组成,每个节点包含数据和...

    c语言中链表的使用

    链表是一种物理存储单元上非连续、非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的。链表由一系列结点(链表中每一个元素称为结点)组成,结点可以在运行时动态生成。每个结点包括两个部分:...

    链表的使用,适合初学者学习

    对于初学者来说,这是一份很好的学习资料,能够帮助他们理解链表的工作原理,以及如何在实际编程中使用链表。通过阅读和分析代码,可以加深对链表数据结构的理解,并掌握其在不同场景下的应用。同时,还可以学习如何...

    链表类,对链表操作的封装,使用了类模版

    封装了链表的操作,功能有链表的创建,节点的添加(附加),插入(前插、后插和插入到链表头部),删除,得到节点数据,得到节点位置,得到节点总数,释放链表。 使用了类模版,使得可以让节点中的数据为任意类型,...

Global site tag (gtag.js) - Google Analytics