數(shù)據(jù)結(jié)構(gòu)一般都是由c++來(lái)講解并且實(shí)現(xiàn)的,所以如果像我這種沒(méi)學(xué)過(guò)c++而學(xué)過(guò)Java的就很尷尬了,不過(guò)不要以為Java不能實(shí)現(xiàn)數(shù)據(jù)結(jié)構(gòu)那些常用的表啊,樹(shù)啊之類的(不知道有沒(méi)有同學(xué)以為Java沒(méi)有指針,所以一些功能無(wú)法實(shí)現(xiàn)呢氯哮?這是錯(cuò)誤的噢)。這個(gè)學(xué)期學(xué)了數(shù)據(jù)結(jié)構(gòu)這本書(shū)商佛,所以我打算用Java實(shí)現(xiàn)其中表喉钢,隊(duì),棧良姆,樹(shù)出牧。如果你有興趣可以持續(xù)關(guān)注我后續(xù)操作。我的CSDN地址為<a >我的博客</a>,我的個(gè)人博客地址為<a >個(gè)人博客</a>
上次分享的是線性表的實(shí)現(xiàn)歇盼,不知道各位小伙伴有沒(méi)有自己動(dòng)手實(shí)現(xiàn)舔痕,不過(guò)進(jìn)度不能停。今天記錄單鏈表的實(shí)現(xiàn)豹缀。雖然Java并沒(méi)有c++中的指針(真的沒(méi)有嗎伯复?我覺(jué)得應(yīng)該算有的),但是依然可以實(shí)現(xiàn)鏈表邢笙,我們可以在Java中用引用變量指向我們的節(jié)點(diǎn)啸如,讓引用變量代替指針的作用。
接下來(lái)我們就一步步實(shí)現(xiàn)吧氮惯。
首先我們要知道什么是節(jié)點(diǎn)镜遣,在Java中并沒(méi)有struct姥宝,但是我們可以創(chuàng)建一個(gè)Node類來(lái)表示節(jié)點(diǎn)。
public class Node<T> {
private T data; //節(jié)點(diǎn)的數(shù)據(jù)
public Node next; //指向的下一個(gè)節(jié)點(diǎn)
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;
}
}
然后我們需要?jiǎng)?chuàng)建一個(gè)鏈表LinkList類,給它一些基本的屬性方法诱鞠,以及創(chuàng)建構(gòu)造函數(shù)等等蝶溶。
public class LinkList<T> {
private Node head; //頭結(jié)點(diǎn)
private Node tail; //尾結(jié)點(diǎn)
private int size; //鏈表長(zhǎng)度
?
public LinkList() {
head=null;
tail=null;
}
//獲取鏈表長(zhǎng)度
public int getLength(){
return size;
}
//是否含有元素
public boolean isEmpty(){
return size==0;
}
//清空鏈表
public void clear(){
head=null;
tail=null;
size=0;
}
}
完成以上操作就可以創(chuàng)建一個(gè)單鏈表了膝蜈。接下來(lái)實(shí)現(xiàn)LinkList類中的重要方法乙漓。
通過(guò)索引獲取節(jié)點(diǎn)的方法,這應(yīng)該算是一個(gè)中間方法,為實(shí)現(xiàn)插入刪除做鋪墊捣郊。
//通過(guò)索引獲取節(jié)點(diǎn)
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;
}
插入方法:個(gè)人建議分開(kāi)寫(xiě)(我是一起寫(xiě)的辽狈,發(fā)現(xiàn)邏輯會(huì)太亂,反正我最后還是分開(kāi)寫(xiě)了)
1呛牲、頭插入
2刮萌、尾插入
3、中間插入(在這個(gè)方法中包含頭插入與尾插入)
//頭插入
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; //尾節(jié)點(diǎn)后移
}
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);
}
}
刪除方法:
刪除指定位置元素
刪除最后一個(gè)位置的元素
//刪除指定位置的元素
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說(shuō)明刪除的是第一個(gè)元素娘扩,將頭結(jié)點(diǎn)指向下一個(gè)就行
head=head.next;
node=null;
}else{
Node preNode=getNodeByIndex(index-1);
preNode.next=node.next;
//如果刪除的是最后一個(gè)元素着茸,尾節(jié)點(diǎn)前移一位
if(index==size-1){
tail=preNode;
}
}
size--;
}
//刪除最后一個(gè)元素
public void remove(){
delete(size-1);
}
最后實(shí)現(xiàn)其他方法(locate找位置,get通過(guò)索引獲得值畜侦,toString直接輸出數(shù)組),這個(gè)單鏈表的實(shí)現(xiàn)就完成了躯保。
@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)"無(wú)此元素";
return (T) sb;
}
以上就完成了所有操作旋膳,如果小伙伴你懶得實(shí)現(xiàn)了,直接復(fù)制粘貼也可以成功途事,最后附上運(yùn)行結(jié)果圖:
這是單鏈表的實(shí)現(xiàn)验懊,如果要做循環(huán)鏈表只需要將tail尾節(jié)點(diǎn)指向head頭結(jié)點(diǎn)即可,有興趣的小伙伴自己去實(shí)現(xiàn)吧尸变。