單鏈表是最基本的數據結構之一,之前在學數據結構的時候用C語言寫過單鏈表,但是還從來沒用Java寫過,嘗試之後才發現Java用對象實現起來雖然沒有C那麼簡便快捷,但是卻更加靈活。
定義Link鏈表類
這裏我是用內部類來定義每一個鏈表的節點Node,先定義基本的框架,其餘的方法下面一一添加。
class Link{
/**
* 定義鏈表節點,爲了方便數據訪問所以我用內部類
* */
private class Node{
private Object data;
private Node next;
public Node(Object data){
this.data = data;
}
}
private Node root; // 鏈表根節點
private int count = 0; // 保存元素的個數
private int foot = 0; // 保存鏈表的索引
private Object[] resArray; // 返回對象數組
}
鏈表添加數據
定義Node類中添加void addNode(Node newNode)方法
/**
* 增加新節點
* @param newNode 新的Node對象
*/
public void addNode(Node newNode){
if(this.next == null){
this.next = newNode;
}else{ // 向後繼續保存
this.next.addNode(newNode);
}
}
在Link類添加void add(Object obj)方法
/**
* 向鏈表中添加元素
* @param data 添加的數據
* */
public void add(Object data) {
if (data == null) {
return;
} else {
Node newNode = new Node(data);
if (this.root == null) {
this.root = newNode;
} else {
this.root.addNode(newNode);
}
}
this.count ++;
}
獲取鏈表長度
Link類中添加方法int size();
/**
* 獲取鏈表的長度
* @return int
* */
public int size(){
return this.count;
}
判斷鏈表是否爲空
Link類中添加方法boolean isEmpty();
/**
* 判斷鏈表是否爲空
* @return boolean
* */
public boolean isEmpty() {
if (root == null) return true;
return false;
}
查找數據是否存在
在Node類中添加方法boolean containsNode(Object obj)
/**
* 查詢數據是否存在於節點中
* @param data
* @return boolean
*/
public boolean containsNode(Object data){
if(this.data.equals(data)){
return true;
}else{
if(this.next == null){
return false;
}else {
return this.next.containsNode(data);
}
}
}
在Link類中添加方法boolean contains(Object obj)
/**
* 根據節點內容判斷某一個數據是否存在
* @return boolean
* */
public boolean contains(Object data){
if (data == null || this.root == null) return false;
return this.root.containsNode(data);
}
根據索引取得數據
在Node類中添加方法Object getNode(int index)
/**
* 獲取某一索引的節點數據
* @param index 索引
* @return Object
*/
public Object getNode(int index) {
// 使用當前節點索引與index比較,隨後自增,目的是爲了下一步查詢
if(Link.this.foot ++ == index){ // 如果當前節點索引與index相等就返回當前節點的data
return this.data;
}else{
return this.next.getNode(index);
}
}
在Link類中添加方法Object get(int index)
/**
* 根據索引取得數據
* */
public Object get(int index) {
if(index+1 > this.count){
try {
throw new Exception("索引值超出鏈表長度!");
} catch (Exception e) {
e.printStackTrace();
}
return null;
}else{
this.foot = 0;
return this.root.getNode(index);
}
}
根據索引值修改鏈表內容
在Node類添加方法void setNode(int index, Object data)
/**
* 根據索引值設置節點內容
* @param index 索引
* @param data 數據
*/
public void setNode(int index, Object data) {
if(Link.this.foot ++ == index){
this.data = data;
}else {
this.next.setNode(index,data);
}
}
在Link類添加方法void set(int index,Object data)
/**
* 根據索引值修改節點內容
* @param index 節點索引
* @param data 節點數據
*/
public void set(int index,Object data){
if(index+1 > this.count){
try {
throw new Exception("索引值超出鏈表長度!");
} catch (Exception e) {
e.printStackTrace();
}
}else {
this.foot = 0;
this.root.setNode(index,data);
}
}
打印鏈表所有內容
在Node類裏添加void printNode()
/**
* 打印出節點數據內容
* @return
*/
public void printNode() {
System.out.println(this.data);
if(this.next != null){
this.next.printNode();
}
}
在Link類裏添加void print()
/**
* 打印鏈表所有內容
*/
public void print(){
this.foot =0;
if (this.count != 0){
this.root.printNode();
}
}
根據數據內容刪除節點
在Node類中添加方法void removeNode(Node previous, Object data)
/**
* 根據索引值刪除節點
* @param index
*/
public void removeNode(Node previous, Object data) {
if(this.data == data){
previous.next = this.next;
}else {
this.next.removeNode(this,data);
}
}
在Link類中添加方法void remove(Object data)
/**
* 根據數據內容刪除節點
* @param index
*/
public void remove(Object data){
if (!this.contains(data)){
try {
throw new Exception("鏈表內不存在該數據!");
} catch (Exception e) {
e.printStackTrace();
}
}else if(data.equals(this.root.data)){
this.root = this.root.next;
}else{
this.root.next.removeNode(this.root,data);
}
this.count --;
}
返回對象數組
在Link類中添加方法Object[] toArray()
/**
* 將鏈表以對象數組形式返回
* @return
*/
public Object[] toArray(){
if(this.root == null){
return null;
}
this.resArray = new Object[this.count];
this.foot = 0;
while(this.foot != this.count){
resArray[this.foot] = this.get(this.foot);
}
return resArray;
}
測試鏈表
我們在main方法中對上面鏈表的增、刪、改、查進行測試
public class LinkDemo {
public static void main(String[] args) {
// new 一個鏈表對象
Link link = new Link();
System.out.println("--------------------添加數據前-----------------");
System.out.println("鏈表是否爲空:"+link.isEmpty());
System.out.println("鏈表的長度:"+link.size());
// 向鏈表中添加一個字符串對象
link.add("A");
// 向鏈表中添加一個char型數據
link.add('B');
// 向鏈表中添加一個Boolean對象
link.add(true);
// 向鏈表中添加一個int型數據
link.add(123);
// 向鏈表中添加一個集合對象
ArrayList arrayList = new ArrayList<String>();
arrayList.add("hello");
arrayList.add("world");
arrayList.add("!");
link.add(arrayList);
System.out.println("--------------------添加數據後-----------------");
// 判斷是否爲空
System.out.println("鏈表是否爲空:"+link.isEmpty());
// 獲取鏈表長度
System.out.println("鏈表的長度:"+link.size());
// 根據索引值獲取某一個節點數據
System.out.println("獲取第2個節點的數據:"+link.get(1));
// 修改第一個節點數據爲tianzhi
link.set(0,"tianzhi");
System.out.println("修改第1個節點數據爲tianzhi後第1個節點:"+link.get(0));
System.out.println("************刪除節點內容值爲true之前************");
link.print();
// 刪除節點內容值爲true的節點
link.remove(true);
System.out.println("************刪除節點內容值爲true之後************");
link.print();
// 返回對象數組
System.out.println("++++++++++++以下是對象數組輸出++++++++++++");
for (int i = 0;i<link.toArray().length;i++){
System.out.println(link.toArray()[i]);
}
// 測試節點長度越界情況
System.out.println("############以下是測試鏈表越界############");
link.get(100);
}
}
最終輸出結果:
--------------------添加數據前-----------------
鏈表是否爲空:true
鏈表的長度:0
--------------------添加數據後-----------------
鏈表是否爲空:false
鏈表的長度:5
獲取第2個節點的數據:B
修改第1個節點數據爲tianzhi後第1個節點:tianzhi
************刪除節點內容值爲true之前************
tianzhi
B
true
123
[hello, world, !]
************刪除節點內容值爲true之後************
tianzhi
B
123
[hello, world, !]
++++++++++++以下是對象數組輸出++++++++++++
tianzhi
B
123
[hello, world, !]
############以下是測試鏈表越界############
java.lang.Exception: 索引值超出鏈表長度!
at language.Link.get(LinkDemo.java:157)
at language.LinkDemo.main(LinkDemo.java:277)
單鏈表全部代碼
package language;
import java.util.ArrayList;
import java.util.List;
/**
* @Author beifengtz
* @Date Created in 23:07 2018/9/22
* @Description:
*/
class Link{
/**
* 定義鏈表節點
* */
private class Node{
private Object data;
private Node next;
public Node(Object data){
this.data = data;
}
/**
* 增加新節點
* @param newNode 新的Node對象
*/
public void addNode(Node newNode){
if(this.next == null){
this.next = newNode;
}else{ // 向後繼續保存
this.next.addNode(newNode);
}
}
/**
* 查詢數據是否存在於節點中
* @param data
* @return boolean
*/
public boolean containsNode(Object data){
if(this.data.equals(data)){
return true;
}else{
if(this.next == null){
return false;
}else {
return this.next.containsNode(data);
}
}
}
/**
* 獲取某一索引的節點數據
* @param index 索引
* @return Object
*/
public Object getNode(int index) {
// 使用當前節點索引與index比較,隨後自增,目的是爲了下一步查詢
if(Link.this.foot ++ == index){ // 如果當前節點索引與index相等就返回當前節點的data
return this.data;
}else{
return this.next.getNode(index);
}
}
/**
* 根據索引值設置節點內容
* @param index 索引
* @param data 數據
*/
public void setNode(int index, Object data) {
if(Link.this.foot ++ == index){
this.data = data;
}else {
this.next.setNode(index,data);
}
}
/**
* 打印出節點數據內容
* @return
*/
public void printNode() {
System.out.println(this.data);
if(this.next != null){
this.next.printNode();
}
}
/**
* 根據索引值刪除節點
* @param index
*/
public void removeNode(Node previous, Object data) {
if(this.data == data){
previous.next = this.next;
}else {
this.next.removeNode(this,data);
}
}
}
private Node root; // 鏈表根節點
private int count = 0; // 保存元素的個數
private int foot = 0; // 保存鏈表的索引
private Object[] resArray; // 返回的對象數組
/**
* 向鏈表中添加元素
* @param data 添加的數據
* */
public void add(Object data) {
if (data == null) {
return;
} else {
Node newNode = new Node(data);
if (this.root == null) {
this.root = newNode;
} else {
this.root.addNode(newNode);
}
}
this.count ++;
}
/**
* 獲取鏈表的長度
* @return int
* */
public int size(){
return this.count;
}
/**
* 判斷鏈表是否爲空
* @return boolean
* */
public boolean isEmpty() {
if (root == null) return true;
return false;
}
/**
* 根據節點內容判斷某一個數據是否存在
* @return boolean
* */
public boolean contains(Object data){
if (data == null || this.root == null) return false;
return this.root.containsNode(data);
}
/**
* 根據索引取得數據
* */
public Object get(int index) {
if(index+1 > this.count){
try {
throw new Exception("索引值超出鏈表長度!");
} catch (Exception e) {
e.printStackTrace();
}
return null;
}else{
this.foot = 0;
return this.root.getNode(index);
}
}
/**
* 根據索引值修改節點內容
* @param index 節點索引
* @param data 節點數據
*/
public void set(int index,Object data){
if(index+1 > this.count){
try {
throw new Exception("索引值超出鏈表長度!");
} catch (Exception e) {
e.printStackTrace();
}
}else {
this.foot = 0;
this.root.setNode(index,data);
}
}
/**
* 打印鏈表所有內容
*/
public void print(){
this.foot =0;
if (this.count != 0){
this.root.printNode();
}
}
/**
* 根據數據內容刪除節點
* @param index
*/
public void remove(Object data){
if (!this.contains(data)){
try {
throw new Exception("鏈表內不存在該數據!");
} catch (Exception e) {
e.printStackTrace();
}
}else if(data.equals(this.root.data)){
this.root = this.root.next;
}else{
this.root.next.removeNode(this.root,data);
}
this.count --;
}
/**
* 將鏈表以對象數組形式返回
* @return
*/
public Object[] toArray(){
if(this.root == null){
return null;
}
this.resArray = new Object[this.count];
this.foot = 0;
while(this.foot != this.count){
resArray[this.foot] = this.get(this.foot);
}
return resArray;
}
}
public class LinkDemo {
public static void main(String[] args) {
// new 一個鏈表對象
Link link = new Link();
System.out.println("--------------------添加數據前-----------------");
System.out.println("鏈表是否爲空:"+link.isEmpty());
System.out.println("鏈表的長度:"+link.size());
// 向鏈表中添加一個字符串對象
link.add("A");
// 向鏈表中添加一個char型數據
link.add('B');
// 向鏈表中添加一個Boolean對象
link.add(true);
// 向鏈表中添加一個int型數據
link.add(123);
// 向鏈表中添加一個集合對象
ArrayList arrayList = new ArrayList<String>();
arrayList.add("hello");
arrayList.add("world");
arrayList.add("!");
link.add(arrayList);
System.out.println("--------------------添加數據後-----------------");
// 獲取鏈表長度
System.out.println(link.size());
// 判斷是否爲空
System.out.println("鏈表是否爲空:"+link.isEmpty());
System.out.println("鏈表的長度:"+link.size());
// 根據索引值獲取某一個節點數據
System.out.println("獲取第2個節點的數據:"+link.get(1));
// 修改第一個節點數據爲tianzhi
link.set(0,"tianzhi");
System.out.println("修改第1個節點數據爲tianzhi後第1個節點:"+link.get(0));
System.out.println("************刪除節點內容值爲true之前************");
link.print();
// 刪除節點內容值爲true的節點
link.remove(true);
System.out.println("************刪除節點內容值爲true之後************");
link.print();
// 返回對象數組
System.out.println("++++++++++++以下是對象數組輸出++++++++++++");
for (int i = 0;i<link.toArray().length;i++){
System.out.println(link.toArray()[i]);
}
// 測試節點長度越界情況
System.out.println("############以下是測試鏈表越界############");
link.get(100);
}
}
我的個人博客地址:blog.beifengtz.com