链表分析和简单自定义单链表的实现

1.概念
链接存储结构,也称为动态存储结构。与顺序存储结构不同,链接存储结构不要求逻辑上相邻的两个元素在物理位置上也相邻,这就为我们动态的为每个结点分配存储空间提供了可能。链接存储时最常见的存储结构之一,其通过在数据元素之后附加一个指向其相邻数据元素存储地址地链接指针的方法来表示数据元素之间的逻辑关系。我们把一个数据元素和它的链接指针所构成的结构称为一个结点(node),每个结点不仅含有所存元素本身信息,也含有表示数据元素之间逻辑关系的信息。
通常把用于处理逻辑上具有线性关系的链接存储结构称为链表,在链表结构中表示数据的元素本身的信息称为数据属性(data),把表示数据元素之间逻辑关系的信息关系称为指针属性(pointer)
一个结点可以有多数据元素属性,但最多只有两个指针属性。

2.优缺点分析

优点:
1).链接储存结构不要求逻辑上相邻的元素在物理位置上也相近,通过指针属性来表示数据元素之间的关系。
2).链接储存结构不是一次性的为所有的数据元素分配储存空间,而是以结点为单位,动态的为每一个结点独立的分配存储空间。因此,其有利于存储空间的使用和分配。
3).适合处理数据序列中数据数量变化较大的问题
4).其不仅可以处理线性结构,也是处理树状结构和网状结构问题的最基本的存储结构。

缺点:
1).不能随机的访问其中的任意一个结点,不适合需要经常性的大量查找运算的数据处理问题。
2).链接存储结构至少需要一个指针属性来存储相邻元素的存储地址,因此如果数据过于简单的话,则会造成内存的浪费

3.创建单链表结点类的一个实例
1)构造一个结点类Node

public class Node {

Object num,name,score;//结点中的数据属性 Object
Node next;//节点中的指针属性,指向下一个Node对象
public Node(Object ob1,Object ob2,Object ob3){
this.num=ob1;
this.name=ob2;
this.score=ob3;
next=null;
}
2) 创建三个独立的结点
//建立结点
Node node1=new Node(n1, "li", s1);//建立第一个结点
Node node2=new Node(n2,"wang",s2);//建立第二个结点
Node node3=new Node(n3,"zhao",s3);//建立第三个结点

3)单链表中结点链接方法
Node1.next=Node2;//Node1.next是指向Node2的引用
Node2.next=Node3;
Node3.next=null;//Node3.next指向空


4.单链表类的抽象描述
public class List(){
Node head,tail; //定义头尾结点
String Lname; //定义链表名字
//构造方法
public List(String name){
Lname=name;head=null;tail=null;
}
public List(){
Lname="List";head=null;tail=null;
}

public void appendToFront(Node n){
添加结点到头部
}

public vioi appendToTail(Node n){
添加结点到尾部
}

public void visitList(){
遍历链表
}

public Node getNode(int i){
查找链表中第i个结点
}

public void insert(Node n,int i){
添加结点n到链表中的第i个结点以后
}

public void delete(int i){
删除第i个结点
}
}

5.自定义单链表的实现
1).创造一个空链表
public class List(){
Node head,tail; //定义头尾结点
String Lname; //定义链表名字
//构造方法
public List(String name){
Lname=name;head=null;tail=null;
}
public List(){
Lname="List";head=null;tail=null;
}
}
2)添加结点
因为最初创建的链表没有节点所以head和tail都为null.当第一次插入结点的head=node1;tail=Node1;
如果再次添,就有两种不同的方法:一种是将每一个新结点插到链表头部,其需要修改head而tail不变,执行的关键语句是Node2.next=head;head=Node2;
相反则是插到尾部,head不变而tail变化,关键语句是tail.next=node2;tail=node2;

其代码实现为:
头插法:
public void appendToFront(Node n){
if(head==null){//链表为空
head=n;
tail=n;
}else{
n.next=head;
head=n;
}
}
尾插法:
public void appendToTail(Node n){
if(head==null){
head=n;
tail=n;
}else{
tail.next=n;
tail=n;
}
}

3)遍历单链表
首先定义一个head结点对象的引用,将P结点的数据输出,再将P移向下一个节点对象的引用,即p=p.next;当p.next为空的时候,结束该过程。
代码实现为:
public void visitList(){
//首先定义一个Node类对象P成为head的引用
Node p=head;
if(p==null){
System.out.println("此为空链表");
}else{
while(true){
System.out.println(p.num.toString()+" "+p.name.toString()
+" "+p.score.toString()+""+"->");
if(p.next==null)break;
p=p.next;

}
}
}
4)打印长度
定义一个head对象的引用和一个计数器size,每执行一次p=p.next,size++,到P=null时程序结束
代码实现为:
public int getSize(){
int size=0;
Node p=head;
if(p==null)size=0;
else{
while(true){
size++;
if(p.next==null)break;
p=p.next;
}
}
return size;
}
5)查找结点
定义一个head对象的引用P,利用for循环反复循执行p=p.next,次数为i-1;
代码实现为:
public Node getNode(int i){
if(i>this.getSize())return null;
Node p=head;
if(i==1)return p;
for(int j=0;j<i-1;j++){
p=p.next;
}
return p;
}
6)插入结点n到链表中第i个结点之后
首先查找第i个结点,设p为该结点的引用。判断p是否为空,是则结束。再判断p.next是否为空以说明p是否为链表中最后一个结点。是则令p.next=n;tail=n插到最后;不是则,n.next=p.next,p.next=n插至中间;
代码实现为:
public void insert(Node n, int i) {
if (i > this.getSize()) {
System.out.println("错误请重新输入");
} else {
// 先找到第i个节点
Node p = head;
for (int j = 0; j < i-1; j++) {
p = p.next;
}
//把n插入p后面去
if(p.next==null){
p.next=n;
tail=n;
}else{
n.next=p.next;
p.next=n;
}
}
7)将第i个结点删除
原理同上。
代码实现为:
public void delete(int i) {
// 首先获取第i个结点
Node p = this.getNode(i);
Node pre=null;
if(p==null){
System.out.println("输入错误请重新输入");
} else if (i == 1) {// 如果i=1
head = head.next;
} else{//获取其前驱结点
pre=getNode(i-1);
//进行判断p是否为尾结点
if(p.next==null){//是尾结点
pre.next=null;
tail=pre;
}else{//不是尾结点
pre.next=p.next;
}
}
}
8)清空链表
只需将头尾结点设置为null就可以了
head=null;tail=null
至此单链表功能基本实现。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值