数据结构之单链表的实现-java
一、单链表基本概念
单链表是一种链式存取的数据结构,用一组地址任意的存储单元(一般是非连续存储单元)存放线性表中的数据元素。链表中的数据是以结点来表示的,每个结点的构成:元素data + 指针next(指示后继元素存储位置)。其存储结构如图:

二、JAVA实现单链表
数据结构:
单链表有一个属性head和一些重要的方法,head为链表结点Node类的实例。Node类中包含成员变量:data,next。data为当前节点的数据域,next为指针域,指向下一个结点。
1、结点
class Node{
int data;
Node next=null;
public Node(int data){
this.data=data;
}
public Node(){}
public void display() {
System. out.print(this.data + " "); //结点打印函数
}
}
2、单链表
public class linkList {
Node head=new Node();
//各种方法的实现代码
}
函数
1、链表添加元素之头插
每次来了新元素将其插入到头结点之后
public void insertHead(int val){
Node newnode=new Node(val);
if(head.next!=null){
newnode.next=head.next;
}
head.next=newnode;
}
2、链表添加元素之尾插
每次来了新元素将其插入到链表最后位置
public void insertTail(int val){
Node newnode=new Node(val);
Node walkPointer=head;
while(walkPointer.next!=null){
walkPointer=walkPointer.next;
}
walkPointer.next=newnode;
}
3、任意位置插入
public void insert(int pos,int val){
int index=0;
if(pos>=0&&pos<=this.getLength()){
Node walkPointer=head;
while(index!=pos){
walkPointer=walkPointer.next;
index++;
}
Node newnode=new Node(val);
newnode.next=walkPointer.next;
walkPointer.next=newnode;
}
}
4、获取链表长度
public int getLength(){
int length=0;
Node walkPointer=head;
while(walkPointer.next!=null){
walkPointer=walkPointer.next;
length++;
}
return length;
}
5、删除指定结点(头指针未知):实质用该结点代替其next结点
public boolean delete(Node delnode){
if(delnode==null||delnode.next==null){
return false;
}
delnode=delnode.next;
return true;
}
6、遍历链表
public void print() {
Node walkPointer=head;
System.out.println("**链表结点遍历**");
while(walkPointer.next!=null){
walkPointer=walkPointer.next;
System.out.print(walkPointer.data + " ");
}
System.out.println();
}
7、链表逆置
之前遇到一道题目,需要将链表元素从尾到头创建ArrayList数组的题目,这里相同的思路,只不过是逆序输出创建新的链表。
两者不同之处在于:对于非递归的方式,链表逆序输出创建新数组时,采用头插的方式相对费时,需要将第一个元素之后的元素后移;而链表逆序输出创建新链表时,采用头插的方式相对快速,只要找到头结点即可一步插入。相反的,对于递归的方式,链表逆序输出创建新数组时,采用尾插的方式相比创建新链表要省时。
思路1:(递归)将链表结点的数据顺序取出存储在栈中——从栈中pop元素采用尾插的方式建立新链表(链表的尾插比较费时,需要遍历到链表最后一个元素才能插入元素)
public linkList reverse1(){
linkList list=new linkList();
Stack<Integer> stack=new Stack<Integer>();
Node walkPointer=head.next;
while(walkPointer!=null){
stack.push(walkPointer.data);
walkPointer=walkPointer.next;
}
while(!stack.empty()){
list.insertTail(stack.pop());
}
return list;
}
思路2:(非递归)声明新链表,将原链表元素顺序取出,同时采用头插的方式插入到新链表中(链表的头插相对于尾插耗时更小)
public linkList reverse(){
linkList list=new linkList();
Node walkPointer=head.next;
Node temp=new Node();
while(walkPointer!=null){
list.insertHead(walkPointer.data);
walkPointer=walkPointer.next;
}
return list;
}
整体代码(含测试)
package struct;
import java.util.Stack;
class Node{
int data;
Node next=null;
public Node(int data){
this.data=data;
}
public Node(){}
public void display() {
System. out.print(this.data + " "); //结点打印函数
}
}
public class linkList {
Node head=new Node();
//头插
public void insertHead(int val){
Node newnode=new Node(val);
if(head.next!=null){
newnode.next=head.next;
}
head.next=newnode;
}
//尾插
public void insertTail(int val){
Node newnode=new Node(val);
Node walkPointer=head;
while(walkPointer.next!=null){
walkPointer=walkPointer.next;
}
walkPointer.next=newnode;
}
//获得链表长度
public int getLength(){
int length=0;
Node walkPointer=head;
while(walkPointer.next!=null){
walkPointer=walkPointer.next;
length++;
}
return length;
}
//任意位置插入
public void insert(int pos,int val){
int index=0;
if(pos>=0&&pos<=this.getLength()){
Node walkPointer=head;
while(index!=pos){
walkPointer=walkPointer.next;
index++;
}
Node newnode=new Node(val);
newnode.next=walkPointer.next;
walkPointer.next=newnode;
}
}
//链表的逆置(非递归,同从尾到头构建列表,链表的头插复杂度比列表头插低很多)
public linkList reverse(){
linkList list=new linkList();
Node walkPointer=head.next;
Node temp=new Node();
while(walkPointer!=null){
list.insertHead(walkPointer.data);
walkPointer=walkPointer.next;
}
return list;
//笨方法
// Node preNode=head;
// Node walkPointer=head.next;
// head.next=null;
// Node nextNode=new Node();
// while(walkPointer!=null){
// nextNode=walkPointer.next;
// walkPointer.next=preNode;
// preNode=walkPointer;
// walkPointer=nextNode;
// }
// list.head.next=preNode;
// return list;
}
//链表的逆置(递归,使用栈。类似于从尾到头输出列表)
public linkList reverse1(){
linkList list=new linkList();
Stack<Integer> stack=new Stack<Integer>();
Node walkPointer=head.next;
while(walkPointer!=null){
stack.push(walkPointer.data);
walkPointer=walkPointer.next;
}
while(!stack.empty()){
list.insertTail(stack.pop());
}
return list;
}
//删除指定结点(头指针未知),实质用该结点代替其next结点
public boolean delete(Node delnode){
if(delnode==null||delnode.next==null){
return false;
}
delnode=delnode.next;
return true;
}
//打印遍历
public void print() {
Node walkPointer=head;
System.out.println("**链表结点遍历**");
while(walkPointer.next!=null){
walkPointer=walkPointer.next;
System.out.print(walkPointer.data + " ");
}
System.out.println();
}
@SuppressWarnings("null")
public static void main(String []args){
linkList list=new linkList();
list.insertHead(12);
list.insertHead(15);
list.insertHead(2);
list.insertHead(3);
list.insert(0,4);
list.print();
System.out.println("链表长度");
System.out.println(list.getLength());
System.out.println("!!链表转置后的头结点数据!!");
linkList returnlist=new linkList();
returnlist=list.reverse();
returnlist.print();
returnlist=list.reverse1();
returnlist.print();
}
}
数据结构之单链表的实现-java的更多相关文章
- 数据结构(一) 单链表的实现-JAVA
数据结构还是很重要的,就算不是那种很牛逼的,但起码得知道基础的东西,这一系列就算是复习一下以前学过的数据结构和填补自己在这一块的知识的空缺.加油.珍惜校园中自由学习的时光.按照链表.栈.队列.排序.数 ...
- 数据结构(2):单链表学习使用java实现
单链表是单向链表,它指向一个位置: 单链表常用使用场景:根据序号排序,然后存储起来. 代码Demo: package com.Exercise.DataStructure_Algorithm.Sing ...
- 数据结构之单链表(基于Java实现)
链表:在计算机中用一组任意的存储单元存储线性表的数据元素称为链式存储结构,这组存储结构可以是连续的,也可以是不连续的,因此在存储数据元素时可以动态分配内存. 注:在java中没有指针的概念,可以理解为 ...
- Python数据结构之单链表
Python数据结构之单链表 单链表有后继结点,无前继结点. 以下实现: 创建单链表 打印单链表 获取单链表的长度 判断单链表是否为空 在单链表后插入数据 获取单链表指定位置的数据 获取单链表指定元素 ...
- 理解单链表的反转(java实现)
要求很简单,输入一个链表,反转链表后,输出新链表的表头. 反转链表是有2种方法(递归法,遍历法)实现的,面试官最爱考察的算法无非是斐波那契数列和单链表反转,递归方法实现链表反转比较优雅,但是对于不 ...
- javascript数据结构之单链表
下面是用javascript实现的单链表,但是在输出的时候insert方法中存在问题,chrome的console报错说不能读取空的属性,调试了很久都没有通过,先在这里存着,以后再来修改一下. //数 ...
- Java数据结构之单链表
这篇文章主要讲解了通过java实现单链表的操作,一般我们开始学习链表的时候,都是使用C语言,C语言中我们可以通过结构体来定义节点,但是在Java中,我们没有结构体,我们使用的是通过类来定义我们所需要的 ...
- Java数据结构-03单链表(二)
在之前我们封装了一些操作在接口类中,并在抽象类实现了相同的方法.下面我们开始写代码: 无头结点单链表:(注意下面的AbstractList是之前抽取的类,不是java.util包下的类) public ...
- 图解Java数据结构之单链表
本篇文章介绍数据结构中的单链表. 链表(Linked List)介绍 链表可分为三类: 单链表 双向链表 循环列表 下面具体分析三个链表的应用. 单链表 链表是有序的列表,它在内存中存储方式如下: 虽 ...
随机推荐
- Django 详解
Django是一个开源的Web应用框架,由Python写成.采用MVC的软件设计模式,主要目标是使得开发复杂的.数据库驱动的网站变得简单.Django注重组件的重用性和“可插拔性”,敏捷开发和DRY法 ...
- 统计mysql某个数据库的表数量以及表记录数
统计MySQL中某个数据库中有多少张表 SELECT count(*) TABLES, table_schema FROM information_schema.TABLES where ...
- 读redux源码总结
redux介绍 redux给我们暴露了这几个方法 { createStore, combineReducers, bindActionCreators, applyMiddleware, compos ...
- Java file.encoding
1. file.encoding属性的作用 file.encoding 的值是整个程序使用的编码格式. 可以使用 System.out.println(System.getProperty(&quo ...
- Omnigraffle
OmniGraffle 7 Mac 注册码 账号:Appked 密码:MFWG-GHEB-HYTW-CGHT-CSXU-QCNC-SXU https://blog.csdn.net/ChibiMaru ...
- [SQL Server 视图的创建- (create view必须是批处理中仅有的语句问题)]
当我们SQL Server在创建视图时 ,会出现"create view 必须是批处理中仅有的语句"这个语法错误提示 ,实际上这本身没什么错! 因为create view 必须是批 ...
- GitHub-Microsoft:DotNet4
ylbtech-GitHub-Microsoft:DotNet4 1.返回顶部 · dotnet-template-samples Samples showing how to create temp ...
- DDNS是动态域名解析的意思
目前大部分家庭使用PPPOE拨号方式上网,每次上网获得的IP都是随机变换的,但是家里的网络监控.智能设备需要通过网络访问,每次使用都需要先知道IP非常麻烦. 有了DDNS动态域名解析,我们只要到花生壳 ...
- 前端之路(二)之JavaScript:菜鸟教程学习:http://www.runoob.com/js/js-intro.html
JavaScript 语句和 JavaScript 变量都对大小写敏感. 键值对通常写法为 name : value (键与值以冒号分割). 键值对在 JavaScript 对象通常称为 对象属性. ...
- pagehelper用法
spring boot 和 mybatis 中使用 pagehelper: 1. 在pom.xml 中加入pagehelper的引用: <dependency> <groupId&g ...