單向鏈表

鏈表本身也是線性表捎迫,只不過物理存儲(chǔ)上不連續(xù)

//線性表接口
public interface List {
    //獲得線性表長度
    public int size();

    //判斷線性表是否為空
    public boolean isEmpty();

    //插入元素
    public void insert(int index, Object obj) throws Exception;

    //刪除元素
    public void delete(int index) throws Exception;

    //獲取指定位置的元素
    public Object get(int index) throws Exception;
}

Node.java:結(jié)點(diǎn)類

//結(jié)點(diǎn)類
public class Node {

    Object element; //數(shù)據(jù)域
    Node next;  //指針域

    //頭結(jié)點(diǎn)的構(gòu)造方法
    public Node(Node nextval) {
        this.next = nextval;
    }

    //非頭結(jié)點(diǎn)的構(gòu)造方法
    public Node(Object obj, Node nextval) {
        this.element = obj;
        this.next = nextval;
    }

    //獲得當(dāng)前結(jié)點(diǎn)的指針域
    public Node getNext() {
        return this.next;
    }

    //獲得當(dāng)前結(jié)點(diǎn)數(shù)據(jù)域的值
    public Object getElement() {
        return this.element;
    }
    //設(shè)置當(dāng)前結(jié)點(diǎn)的指針域
    public void setNext(Node nextval) {
        this.next = nextval;
    }

    //設(shè)置當(dāng)前結(jié)點(diǎn)數(shù)據(jù)域的值
    public void setElement(Object obj) {
        this.element = obj;
    }

    public String toString() {
        return this.element.toString();
    }
}

LinkList.java:單向鏈表類(核心代碼)

//單向鏈表類
public class LinkList implements List {

    Node head; //頭指針
    Node current;//當(dāng)前結(jié)點(diǎn)對(duì)象
    int size;//結(jié)點(diǎn)個(gè)數(shù)
    
    //初始化一個(gè)空鏈表
    public LinkList()
    {
        //初始化頭結(jié)點(diǎn),讓頭指針指向頭結(jié)點(diǎn)倔既。并且讓當(dāng)前結(jié)點(diǎn)對(duì)象等于頭結(jié)點(diǎn)。
        this.head = current = new Node(null);
        this.size =0;//單向鏈表,初始長度為零醇滥。
    }
    
    //定位函數(shù)黎比,實(shí)現(xiàn)當(dāng)前操作對(duì)象的前一個(gè)結(jié)點(diǎn),也就是讓當(dāng)前結(jié)點(diǎn)對(duì)象定位到要操作結(jié)點(diǎn)的前一個(gè)結(jié)點(diǎn)鸳玩。
    //比如我們要在a2這個(gè)節(jié)點(diǎn)之前進(jìn)行插入操作阅虫,那就先要把當(dāng)前節(jié)點(diǎn)對(duì)象定位到a1這個(gè)節(jié)點(diǎn),然后修改a1節(jié)點(diǎn)的指針域
    public void index(int index) throws Exception
    {
        if(index <-1 || index > size -1)
        {
          throw new Exception("參數(shù)錯(cuò)誤不跟!");    
        }
        //說明在頭結(jié)點(diǎn)之后操作颓帝。
        if(index==-1)    //因?yàn)榈谝粋€(gè)數(shù)據(jù)元素結(jié)點(diǎn)的下標(biāo)是0,那么頭結(jié)點(diǎn)的下標(biāo)自然就是-1了窝革。
            return;
        current = head.next;
        int j=0;//循環(huán)變量
        while(current != null&&j<index)
        {
            current = current.next;
            j++;
        }
        
    }    
    
    @Override
    public void delete(int index) throws Exception {
        // TODO Auto-generated method stub
        //判斷鏈表是否為空
        if(isEmpty())
        {
            throw new Exception("鏈表為空购城,無法刪除!");
        }
        if(index <0 ||index >size)
        {
            throw new Exception("參數(shù)錯(cuò)誤虐译!");
        }
        index(index-1);//定位到要操作結(jié)點(diǎn)的前一個(gè)結(jié)點(diǎn)對(duì)象工猜。
        current.setNext(current.next.next);
        size--;
    }

    @Override
    public Object get(int index) throws Exception {
        // TODO Auto-generated method stub
        if(index <-1 || index >size-1)
        {
            throw new Exception("參數(shù)非法!");
        }
        index(index);
        
        return current.getElement();
    }

    @Override
    public void insert(int index, Object obj) throws Exception {
        // TODO Auto-generated method stub
        if(index <0 ||index >size)
        {
            throw new Exception("參數(shù)錯(cuò)誤菱蔬!");
        }
        index(index-1);//定位到要操作結(jié)點(diǎn)的前一個(gè)結(jié)點(diǎn)對(duì)象。
        current.setNext(new Node(obj,current.next));
        size++;
    }

    @Override
    public boolean isEmpty() {
        // TODO Auto-generated method stub
        return size==0;
    }

    @Override
    public int size() {
        // TODO Auto-generated method stub
        return this.size;
    } 
    
}

測試代碼

public class LinkListTest {
    public static void main(String[] args) throws Exception {
        LinkList list = new LinkList();
        for (int i = 0; i < 10; i++) {
            int temp = ((int) (Math.random() * 100)) % 100;
            list.insert(i, temp);
            System.out.print(temp + " ");
        }

        list.delete(4);
        System.out.println("\n------刪除第五個(gè)元素之后-------");
        for (int i = 0; i < list.size; i++) {
            System.out.print(list.get(i) + " ");
        }
    }
}

測試代碼輸出

31 98 25 18 10 34 1 20 57 81 
------刪除第五個(gè)元素之后-------
31 98 25 18 34 1 20 57 81 

另外一種實(shí)現(xiàn)史侣,將節(jié)點(diǎn)類Node改為內(nèi)部類

/**
 * 單向鏈表另外一種實(shí)現(xiàn)拴泌,將節(jié)點(diǎn)類Node改為內(nèi)部類
 * 
 * @author adminjack
 *
 */
public class LinkList2 {

    private int size;
    private Node root; // 定義一個(gè)根節(jié)點(diǎn)

    private int foot = 0; // 操作返回?cái)?shù)組的腳標(biāo)
    private String[] retData; // 返回?cái)?shù)組
    private boolean changeFlag = true;
    // changeFlag == true:數(shù)據(jù)被更改了,則需要重新遍歷
    // changeFlag == false:數(shù)據(jù)沒有更改惊橱,不需要重新遍歷

    // 添加數(shù)據(jù)
    public boolean add(String data) {

        if (data == null) { // 如果添加的是一個(gè)空數(shù)據(jù)蚪腐,那增加失敗
            return false;
        }

        // 將數(shù)據(jù)封裝為節(jié)點(diǎn),目的:節(jié)點(diǎn)有next可以處理關(guān)系
        Node newNode = new Node(data);
        // 鏈表的關(guān)鍵就在于根節(jié)點(diǎn)
        if (root == null) { // 如果根節(jié)點(diǎn)是空的税朴,那么新添加的節(jié)點(diǎn)就是根節(jié)點(diǎn)回季。(第一次調(diào)用add方法時(shí),根節(jié)點(diǎn)當(dāng)然是空的了)
            root = newNode;
        } else {
            root.addNode(newNode);
        }

        this.size++;
        return true;

    }

    // 方法:增加一組數(shù)據(jù)
    public boolean addAll(String data[]) { // 一組數(shù)據(jù)
        for (int x = 0; x < data.length; x++) {
            if (!this.add(data[x])) { // 只要有一次添加不成功正林,那就是添加失敗
                return false;
            }
        }
        return true;
    }

    // 方法:刪除數(shù)據(jù)
    public boolean remove(String data) { // 要?jiǎng)h除的節(jié)點(diǎn)泡一,假設(shè)每個(gè)節(jié)點(diǎn)的data都不一樣

        if (!this.contains(data)) { // 要?jiǎng)h除的數(shù)據(jù)不存在
            return false;
        }

        if (root != null) {
            if (root.data.equals(data)) { // 說明根節(jié)點(diǎn)就是需要?jiǎng)h除的節(jié)點(diǎn)
                root = root.next; // 讓根節(jié)點(diǎn)的下一個(gè)節(jié)點(diǎn)成為根節(jié)點(diǎn),自然就把根節(jié)點(diǎn)頂?shù)袅寺铮ú幌駭?shù)組那樣觅廓,要將后面的數(shù)據(jù)在內(nèi)存中整體挪一位)
            } else { // 否則
                root.removeNode(data);
            }
        }
        size--;
        return true;

    }

    // 輸出所有節(jié)點(diǎn)
    public void print() {
        if (root != null) {
            System.out.print(root.data);
            root.printNode();
            System.out.println();
        }
    }

    // 方法:獲取全部數(shù)據(jù)
    public String[] toArray() {
        if (this.size == 0) {
            return null; // 沒有數(shù)據(jù)
        }
        this.foot = 0; // 清零
        this.retData = new String[this.size]; // 開辟數(shù)組大小
        this.root.toArrayNode();
        return this.retData;
    }

    // 獲取數(shù)據(jù)的長度
    public int size() {
        return this.size;
    }

    // 判斷是否為空鏈表
    public boolean isEmpty() {
        return this.size == 0;
    }

    // 清空鏈表
    public void clear() {
        this.root = null;
        this.size = 0;
    }

    // 查詢數(shù)據(jù)是否存在
    public boolean contains(String data) { // 查找數(shù)據(jù)
        // 根節(jié)點(diǎn)沒有數(shù)據(jù)鼻忠,查找的也沒有數(shù)據(jù)
        if (this.root == null || data == null) {
            return false; // 不需要進(jìn)行查找了
        }
        return this.root.containsNode(data); // 交給Node類處理
    }

    // 方法:根據(jù)索引取得數(shù)據(jù)
    public String get(int index) {
        if (index > this.size) { // 超過個(gè)數(shù)
            return null; // 返回null
        }
        this.foot = 0; // 操作foot來定義腳標(biāo)
        return this.root.getNode(index);
    }

    // 定義一個(gè)節(jié)點(diǎn)內(nèi)部類(假設(shè)要保存的數(shù)據(jù)類型是字符串)
    // 比較好的做法是,將Node定義為內(nèi)部類杈绸,在這里面去完成增刪帖蔓、等功能,然后由LinkList去調(diào)用增瞳脓、刪的功能
    class Node {
        private String data;
        private Node next; // next表示:下一個(gè)節(jié)點(diǎn)對(duì)象(單鏈表中)

        public Node(String data) {
            this.data = data;
        }

        // 添加節(jié)點(diǎn)
        public void addNode(Node newNode) {

            // 下面這段用到了遞歸塑娇,需要反復(fù)理解
            if (this.next == null) { // 遞歸的出口:如果當(dāng)前節(jié)點(diǎn)之后沒有節(jié)點(diǎn),說明我可以在這個(gè)節(jié)點(diǎn)后面添加新節(jié)點(diǎn)
                this.next = newNode; // 添加新節(jié)點(diǎn)
            } else {
                this.next.addNode(newNode); // 向下繼續(xù)判斷劫侧,直到當(dāng)前節(jié)點(diǎn)之后沒有節(jié)點(diǎn)為止
            }
        }

        // 判斷節(jié)點(diǎn)是否存在
        public boolean containsNode(String data) { // 查找數(shù)據(jù)
            if (data.equals(this.data)) { // 與當(dāng)前節(jié)點(diǎn)數(shù)據(jù)吻合
                return true;
            } else { // 與當(dāng)前節(jié)點(diǎn)數(shù)據(jù)不吻合
                if (this.next != null) { // 還有下一個(gè)節(jié)點(diǎn)
                    return this.next.containsNode(data);
                } else { // 沒有后續(xù)節(jié)點(diǎn)
                    return false; // 查找不到
                }
            }
        }

        // 刪除節(jié)點(diǎn)
        public void removeNode(String data) {
            if (this.next != null) {
                if (this.next.data.equals(data)) {
                    this.next = this.next.next;
                } else {
                    this.next.removeNode(data);
                }
            }
        }

        // 輸出所有節(jié)點(diǎn)
        public void printNode() {
            if (this.next != null) {
                System.out.print("-->" + this.next.data);
                this.next.printNode();
            }
        }

        // 獲取全部數(shù)據(jù)
        public void toArrayNode() {
            LinkList2.this.retData[LinkList2.this.foot++] = this.data;
            if (this.next != null) {
                this.next.toArrayNode();
            }
        }

        // 根據(jù)索引位置獲取數(shù)據(jù)
        public String getNode(int index) {
            if (LinkList2.this.foot++ == index) { // 當(dāng)前索引為查找數(shù)值
                return this.data;
            } else {
                return this.next.getNode(index);
            }
        }

    }
}
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末埋酬,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌奇瘦,老刑警劉巖棘催,帶你破解...
    沈念sama閱讀 218,122評(píng)論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異耳标,居然都是意外死亡醇坝,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,070評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門次坡,熙熙樓的掌柜王于貴愁眉苦臉地迎上來呼猪,“玉大人,你說我怎么就攤上這事砸琅∷尉啵” “怎么了?”我有些...
    開封第一講書人閱讀 164,491評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵症脂,是天一觀的道長谚赎。 經(jīng)常有香客問我,道長诱篷,這世上最難降的妖魔是什么壶唤? 我笑而不...
    開封第一講書人閱讀 58,636評(píng)論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮棕所,結(jié)果婚禮上闸盔,老公的妹妹穿的比我還像新娘。我一直安慰自己琳省,他們只是感情好迎吵,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,676評(píng)論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著针贬,像睡著了一般击费。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上桦他,一...
    開封第一講書人閱讀 51,541評(píng)論 1 305
  • 那天荡灾,我揣著相機(jī)與錄音,去河邊找鬼瞬铸。 笑死批幌,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的嗓节。 我是一名探鬼主播荧缘,決...
    沈念sama閱讀 40,292評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢(mèng)啊……” “哼拦宣!你這毒婦竟也來了截粗?” 一聲冷哼從身側(cè)響起信姓,我...
    開封第一講書人閱讀 39,211評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎绸罗,沒想到半個(gè)月后意推,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,655評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡珊蟀,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,846評(píng)論 3 336
  • 正文 我和宋清朗相戀三年菊值,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片育灸。...
    茶點(diǎn)故事閱讀 39,965評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡腻窒,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出磅崭,到底是詐尸還是另有隱情儿子,我是刑警寧澤,帶...
    沈念sama閱讀 35,684評(píng)論 5 347
  • 正文 年R本政府宣布砸喻,位于F島的核電站柔逼,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏割岛。R本人自食惡果不足惜卒落,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,295評(píng)論 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望蜂桶。 院中可真熱鬧,春花似錦也切、人聲如沸扑媚。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,894評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽疆股。三九已至,卻和暖如春倒槐,著一層夾襖步出監(jiān)牢的瞬間旬痹,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,012評(píng)論 1 269
  • 我被黑心中介騙來泰國打工讨越, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留两残,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,126評(píng)論 3 370
  • 正文 我出身青樓把跨,卻偏偏與公主長得像人弓,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子着逐,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,914評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容