數據結構一般都是由c++來講解并且實現的,所以如果像我這種沒學過c++而學過Java的就很尷尬了,不過不要以為Java不能實現數據結構那些常用的表啊,樹啊之類的(不知道有沒有同學以為Java沒有指針,所以一些功能無法實現呢?這是錯誤的噢)。這個學期學了數據結構這本書,所以我打算用Java實現其中表,隊,棧,樹。如果你有興趣可以持續關注我后續操作。我的CSDN地址為<a >我的博客</a>,我的個人博客地址為<a >個人博客</a>
上次分享的是線性表的實現,不知道各位小伙伴有沒有自己動手實現,不過進度不能停。今天記錄單鏈表的實現。雖然Java并沒有c++中的指針(真的沒有嗎?我覺得應該算有的),但是依然可以實現鏈表,我們可以在Java中用引用變量指向我們的節點,讓引用變量代替指針的作用。
接下來我們就一步步實現吧。
首先我們要知道什么是節點,在Java中并沒有struct,但是我們可以創建一個Node類來表示節點。
public class Node<T> {
private T data; //節點的數據
public Node next; //指向的下一個節點
public Node(T data, Node next) {
this.data = data;
this.next=next;
}
public Node() { }
public T getData() {
return data;
}
private void setData(T data) {
this.data = data;
}
}
然后我們需要創建一個鏈表LinkList類,給它一些基本的屬性方法,以及創建構造函數等等。
public class LinkList<T> {
private Node head; //頭結點
private Node tail; //尾結點
private int size; //鏈表長度
?
public LinkList() {
head=null;
tail=null;
}
//獲取鏈表長度
public int getLength(){
return size;
}
//是否含有元素
public boolean isEmpty(){
return size==0;
}
//清空鏈表
public void clear(){
head=null;
tail=null;
size=0;
}
}
完成以上操作就可以創建一個單鏈表了。接下來實現LinkList類中的重要方法。
通過索引獲取節點的方法,這應該算是一個中間方法,為實現插入刪除做鋪墊。
//通過索引獲取節點
public Node getNodeByIndex(int index){
if(index<0||index>size-1){
throw new IndexOutOfBoundsException("索引越界");
}
Node node=head;
for(int i=0;i<size;i++,node=node.next){
if(i==index){
return node;
}
}
return null;
}
插入方法:個人建議分開寫(我是一起寫的,發現邏輯會太亂,反正我最后還是分開寫了)
1、頭插入
2、尾插入
3、中間插入(在這個方法中包含頭插入與尾插入)
//頭插入
public void addAtHead(T element){
head=new Node<T>(element, head);
//如果是空鏈表就變讓尾指針指向頭指針
if(tail==null){
tail=head;
}
size++;
}
//尾插入
public void addAtTail(T element){
//如果表為空
if(head==null){
head=new Node<T>(element, null);
tail=head;
}else{
Node node=new Node<T>(element, null);
tail.next=node;
tail=node; //尾節點后移
}
size++;
}
//在指定位置插入元素
public void insert(T element,int index){
if(index<0||index>size){
throw new IndexOutOfBoundsException("索引越界");
}
if(index==0){
addAtHead(element);
}else if(index>0&&index<size-1){
//中間插入
Node nexNode=null;
Node insNode=new Node<T>(element, nexNode);
nexNode=getNodeByIndex(index);
Node preNode=getNodeByIndex(index-1);
preNode.next=insNode;
insNode.next=nexNode;
size++;
}else {
addAtTail(element);
}
}
刪除方法:
刪除指定位置元素
刪除最后一個位置的元素
//刪除指定位置的元素
public void delete(int index){
if(index<0||index>size-1){
throw new IndexOutOfBoundsException("索引越界");
}
int flag=index-1;
Node node=getNodeByIndex(index);
if(flag < 0){
//flag<0說明刪除的是第一個元素,將頭結點指向下一個就行
head=head.next;
node=null;
}else{
Node preNode=getNodeByIndex(index-1);
preNode.next=node.next;
//如果刪除的是最后一個元素,尾節點前移一位
if(index==size-1){
tail=preNode;
}
}
size--;
}
//刪除最后一個元素
public void remove(){
delete(size-1);
}
最后實現其他方法(locate找位置,get通過索引獲得值,toString直接輸出數組),這個單鏈表的實現就完成了。
@Override
public String toString() {
StringBuilder sb=new StringBuilder();
Node node=head;
for(int i=0;i<size;i++,node=node.next)
{
sb=sb.append(node.getData()+" ");
}
return sb+"";
}
?
//獲得指定位置元素
public T get(int index){
return (T) getNodeByIndex(index).getData();
}
//獲得指定元素的索引
public T locate(T element){
Node node=head;
StringBuilder sb=new StringBuilder();
for(int i=0;i<size;i++,node=node.next)
{
if(element.equals(node.getData()))
{
sb=sb.append(i+" ");
}
}
if(sb.length()<=0)
return (T)"無此元素";
return (T) sb;
}
以上就完成了所有操作,如果小伙伴你懶得實現了,直接復制粘貼也可以成功,最后附上運行結果圖:
這是單鏈表的實現,如果要做循環鏈表只需要將tail尾節點指向head頭結點即可,有興趣的小伙伴自己去實現吧。