线性表的Java实现--链式存储(双向链表)
生活随笔
收集整理的這篇文章主要介紹了
线性表的Java实现--链式存储(双向链表)
小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
有了單向鏈表的基礎(chǔ),雙向鏈表的實(shí)現(xiàn)就容易多了。
?
雙向鏈表的一般情況:
?增加節(jié)點(diǎn):
?
刪除節(jié)點(diǎn):
?
雙向鏈表的Java實(shí)現(xiàn):
package?com.liuhao.algorithm;??public?class?DuLinkList<T>?{??/**?*?內(nèi)部類:鏈表中的一個(gè)節(jié)點(diǎn)?*??*?@author?liuhao?data?節(jié)點(diǎn)中的數(shù)據(jù)?prev?指向前一個(gè)節(jié)點(diǎn)的引用?next?指向下一個(gè)節(jié)點(diǎn)的引用?*/??private?class?Node?{??private?T?data;//?保存的數(shù)據(jù)元素??private?Node?prev;//?指向上一個(gè)節(jié)點(diǎn)??private?Node?next;//?指向下一個(gè)節(jié)點(diǎn)??public?Node()?{??}??public?Node(T?data,?Node?prev,?Node?next)?{??super();??this.data?=?data;??this.prev?=?prev;??this.next?=?next;??}??}??private?Node?header;//?頭結(jié)點(diǎn)??private?Node?tail;//?尾節(jié)點(diǎn)??private?int?size;//?鏈表中元素個(gè)數(shù)??//?創(chuàng)建空鏈表??public?DuLinkList()?{??header?=?null;??tail?=?null;??}??//?已指定數(shù)據(jù)元素創(chuàng)建鏈表,只有一個(gè)元素??public?DuLinkList(T?element)?{??header?=?new?Node(element,?null,?null);??//?只有一個(gè)節(jié)點(diǎn),header,tail都指向該節(jié)點(diǎn)??tail?=?header;??size++;??}??//?返回鏈表長(zhǎng)度??public?int?length()?{??return?size;??}??//?獲取指定位置的數(shù)據(jù)元素??public?T?get(int?index)?{??return?this.getNodeByIndex(index).data;??}??//?獲取指定位置的節(jié)點(diǎn)??private?Node?getNodeByIndex(int?index)?{??if?(index?<?0?||?index?>?size?-?1)?{??throw?new?IndexOutOfBoundsException("索引超出線性表范圍");??}??if?(index?<?size?/?2)?{??Node?current?=?header;??for?(int?i?=?0;?i?<?size?/?2?&&?current?!=?null;?i++,?current?=?current.next)?{??if?(i?==?index)?{??return?current;??}??}??}?else?{??Node?current?=?tail;??for?(int?i?=?size?-?1;?i?>=?size?/?2?&&?current?!=?null;?i--,?current?=?current.prev)?{??if?(i?==?index)?{??return?current;??}??}??}??return?null;??}??//?按值查詢所在的位置??public?int?locate(T?element)?{??Node?current?=?header;??for?(int?i?=?0;?i?<?size?-?1?&&?current?!=?null;?i++,?current?=?current.next)?{??if?(element.equals(current.data))?{??return?i;??}??}??return?-1;??}??//?向指定位置插入元素??public?void?insert(T?element,?int?index)?{??if?(index?<?0?||?index?>?size)?{??throw?new?IndexOutOfBoundsException("索引超出線性表范圍");??}??if?(header?==?null)?{??this.add(element);??}?else?{??if?(0?==?index)?{??this.addAtHead(element);??}?else?{??Node?prev?=?this.getNodeByIndex(index?-?1);//?獲取插入節(jié)點(diǎn)的前一個(gè)節(jié)點(diǎn)??Node?next?=?prev.next;//?待插索引處的節(jié)點(diǎn)??Node?newNode?=?new?Node(element,?prev,?next);//?新增節(jié)點(diǎn),讓它的prev指向之前的節(jié)點(diǎn)。next指向之后的節(jié)點(diǎn)??prev.next?=?newNode;//?之前的節(jié)點(diǎn)的next指向當(dāng)前節(jié)點(diǎn)??next.prev?=?newNode;//?之后節(jié)點(diǎn)的prev指向當(dāng)前節(jié)點(diǎn)??size++;??}??}??}??//?采用尾插法添加新節(jié)點(diǎn)??public?void?add(T?element)?{??//?若還是空表,則將header和tail都指向該元素即可??if?(header?==?null)?{??header?=?new?Node(element,?null,?null);??tail?=?header;??}?else?{??//?創(chuàng)建信節(jié)點(diǎn),prev指向tail??Node?newNode?=?new?Node(element,?tail,?null);??//?令tail的next指向新節(jié)點(diǎn)??tail.next?=?newNode;??tail?=?newNode;//?把新節(jié)點(diǎn)設(shè)為尾節(jié)點(diǎn)??}??size++;??}??//?采用頭插發(fā)添加新節(jié)點(diǎn)??public?void?addAtHead(T?element)?{??Node?newNode?=?new?Node(element,?null,?header);??header.prev?=?newNode;??header?=?newNode;??//?如果插入之前是空表??if?(tail?==?null)?{??tail?=?header;??}??size++;??}??//?刪除指定索引處的元素??public?T?delete(int?index)?{??if?(index?<?0?||?index?>?size?-?1)?{??throw?new?IndexOutOfBoundsException("索引超出線性表范圍");??}??Node?del?=?null;??if?(index?==?0)?{??del?=?header;??header?=?header.next;??header.prev?=?null;??}?else?{??Node?prev?=?this.getNodeByIndex(index?-?1);//?獲取索引處之前的節(jié)點(diǎn)??del?=?prev.next;//?獲取索引處的節(jié)點(diǎn)??//?讓之前的節(jié)點(diǎn)的next指向下一個(gè)節(jié)點(diǎn)??prev.next?=?del.next;??//?有可能刪除的是最后一個(gè)元素,若直接調(diào)用next.prev可能會(huì)出錯(cuò)??if?(del.next?!=?null)?{??del.next.prev?=?prev;??}??//若刪除的是最后一個(gè)元素,那么就要重置tail;??tail?=?prev;??del.prev?=?null;??del.next?=?null;??}??size--;??return?del.data;??}??//?刪除最后一個(gè)元素??public?T?remove()?{??return?this.delete(size?-?1);??}??//?判斷是否為空??public?boolean?isEmpty()?{??return?size?==?0;??}??//?清空線性表??public?void?clear()?{??header?=?null;??tail?=?null;??size?=?0;??}??public?String?toString()?{??if?(size?==?0)?{??return?"[]";??}?else?{??StringBuilder?sb?=?new?StringBuilder("[");??for?(Node?current?=?header;?current?!=?null;?current?=?current.next)?{??sb.append(current.data.toString()?+?",?");??}??sb.append("]");??int?len?=?sb.length();??//?刪除多余的“,”和空格??return?sb.delete(len?-?3,?len?-?2).toString();??}??}?? }??測(cè)試代碼:
package com.liuhao.test;import org.junit.Test;import com.liuhao.algorithm.DuLinkList;public class DuLinkListTest {@Testpublic void test() {//測(cè)試構(gòu)造函數(shù)DuLinkList<String> duList = new DuLinkList("好");System.out.println(duList);//測(cè)試添加元素duList.add("ni");duList.add("沒");System.out.println(duList);//在頭部添加duList.addAtHead("五月");System.out.println(duList);//在指定位置添加duList.insert("摩卡", 2);System.out.println(duList);//獲取指定位置處的元素System.out.println("第2個(gè)元素是(從0開始計(jì)數(shù)):" + duList.get(2));//返回元素索引System.out.println("摩卡在的位置是:" + duList.locate("摩卡"));System.out.println("moka所在的位置:" + duList.locate("moka"));//獲取長(zhǎng)度System.out.println("當(dāng)前線性表的長(zhǎng)度:" + duList.length());//判斷是否為空System.out.println(duList.isEmpty());//刪除最后一個(gè)元素duList.remove();System.out.println("調(diào)用remove()后:" + duList);//獲取長(zhǎng)度System.out.println("當(dāng)前線性表的長(zhǎng)度:" + duList.length());//刪除指定位置處元素duList.delete(3);System.out.println("刪除第4個(gè)元素后:" + duList);//獲取長(zhǎng)度System.out.println("當(dāng)前線性表的長(zhǎng)度:" + duList.length());//清空duList.clear();System.out.println(duList);//判斷是否為空System.out.println(duList.isEmpty());}}
轉(zhuǎn)載于:https://www.cnblogs.com/ganchuanpu/p/7468565.html
總結(jié)
以上是生活随笔為你收集整理的线性表的Java实现--链式存储(双向链表)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 只读域控制器在Server Core中的
- 下一篇: 算法及shell脚本编程基础