日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

数据结构-链表结构

發布時間:2023/12/31 编程问答 37 豆豆
生活随笔 收集整理的這篇文章主要介紹了 数据结构-链表结构 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

鏈表結構

鏈表結構的定義

什么是鏈表

鏈表結構是由多個節點構成的,每個節點都包含著兩部分:

  • 數據部分:
    • 保存該節點的實際數據
  • 指針部分:
    • 指向上一個節點或者下一個節點

鏈表分類

  • 單向鏈表
  • 雙向鏈表
  • 雙向循環鏈表

鏈表的特點

  • 節點在存儲器中的位置是任意的,即邏輯上相鄰的數據元素在物理上不一定相鄰。
  • 訪問時只能通過頭或者尾指針進入鏈表,并通過每個節點的指針域向后或向前掃描其余節點,所以尋找第一個結點和最后一個結點所花費的時間不等。

鏈表的優缺點:

優點:

  • 數據元素的個數可以自由擴充,插入,刪除,等操作不必移動數據,只需修改鏈表指針,修改效率較高;

缺點:

  • 必須采用循環存取,即存取數據元素時,只能按元素的順序來進行訪問,訪問節點效率較低;

單向鏈表

單向鏈表定義

特是鏈表的方向是單向的,對鏈表的訪問要通過頭指針從頭節點開始順序的讀取

實現單項鏈表

MyList
public interface MyList<E> {//添加節點數據void add(E element);//獲取節點數據E get (int index);//獲取鏈表長度int size();//根據指針移除節點E remove(int index);}
MyLinkedList
public class MyLinkedList<E> implements MyList<E>{private Node head; //存放鏈表的頭節點private int size;//記錄鏈表長度/*** 向鏈表中添加節點* @param element*/@Overridepublic void add(E element) {//創建節點Node<E> node = new Node<>(element,null);//找到尾節點Node tial = getTail();//節點的連接if (tial == null){this.head = node;}else {tial.next = node;}// 記錄元素個數this.size++;}/*** 找到尾節點*/private Node getTail(){//頭節點是否存在if (this.head == null){return null;}//查找下一個節點Node node = this.head;while (true){if (node.next == null){break;}node = node.next;//移動指針,指向下一個節點}return node;}/*** 根據指針獲取節點數據* @param index* @return*/@Overridepublic E get(int index) {//校驗index的合法性this.pointerIndex(index);//根據位置獲取對應的節點數據Node<E> node = getNode(index);//將節點中的元素返回return node.item;}/*** 根據index進行校驗*/private void pointerIndex(int index){if (!(index >= 0 && index < this.size)){int a = this.size-1;throw new IndexOutOfBoundsException("你輸入的指針為:"+ index +"指針最大為:"+a);}}/*** 根據指針獲取節點*/private Node getNode(int index){Node<E> node = this.head;for (int i = 0 ; i < index;i++){node = node.next;}return node;}/*** 獲取鏈表長度(個數)* @return*/@Overridepublic int size() {return this.size;}/*** 根據指針移除對應的節點* @param index* @return*/@Overridepublic E remove(int index) {//校驗index的合法性this.pointerIndex(index);//根據index指針找到該節點對象數據Node<E> node = this.getNode(index);//獲取該節點對象中的元素E item = node.item;//向該節點對象中單向鏈表刪除//判斷當前刪除的節點是否為頭節點if (this.head == node){this.head = node.next;//如果是刪除頭節點,頭節點的下一個節點,賦值給了頭節點}else {Node<E> node1 = this.head;//拿頭節點for (int i = 0 ; i<index - 1 ; i++){node1=node1.next;}node1.next = node.next;//將節點的下一個節點賦值給該節點}node.next = null;this.size -- ;//刪除成功長度減一return item;//返回元素}/*** 定義單向鏈表中的節點對象* @param <E>*/class Node<E>{private E item;//儲存的元素private Node next;//儲存下一個節點對象的地址public Node() {}Node(E item , Node next){this.item = item;this.next = next;}}}
測試
public static void main(String[] args) {MyLinkedList myLinkedList = new MyLinkedList();myLinkedList.add(12);myLinkedList.add(13);myLinkedList.add(14);myLinkedList.add(15);myLinkedList.add(16);System.out.println("根據指針找到值"+myLinkedList.get(4));System.out.println("刪除的節點"+myLinkedList.remove(0));System.out.println(myLinkedList);System.out.println(myLinkedList.size());for (int i=0;i<myLinkedList.size(); i++){System.out.print(myLinkedList.get(i)+",");}}

雙向循環鏈表

雙向循環鏈表的定義

雙向循環鏈表,也是鏈表的的一種,它的每個數據節點中都有兩個指針,分別指向前驅和后繼。

MyList
public interface MyList<E> {//添加節點數據void add(E element);//獲取節點數據E get (int index);//獲取鏈表長度int size();//根據指針移除節點E remove(int index);//從頭添加元素void addFirst(E element);//從尾添加元素void addLast(E element); }
MyDoubleLinkedList
public class MyDoubleLinkedList<E> implements MyList<E> {private int size;//記錄元素的個數private Node head ;// 記錄頭節點private Node tail;//記錄尾節點/*** 向雙向鏈表中添加元素數據* @param element*/@Overridepublic void add(E element) {this.linkLast(element);}/*** 將節點對象添加到雙向鏈表的尾部* @param element*/private void linkLast(E element){//獲取尾節點Node t = this.tail;Node<E> node = new Node<>(t,element,null);//將新節點定義為尾節點this.tail = node;if (t == null){//當t等于空的時候說明這個鏈表是個空鏈表this.head=node;//將向的元素數據賦值到頭節點}else{t.next=node;//否則將新元素賦值到尾節點之后}this.size++;//添加成功長度自增加一}/*** 根據指針獲取對應的元素數據* @param index* @return*/@Overridepublic E get(int index) {//對index做合法性校驗this.rangeCheck(index);Node<E> node = this.getNode(index);return node.item;}/*** 判斷當前index的合法性*/private void rangeCheck(int index){if(!(index >=0 && index < this.size)){int a = this.size-1;throw new IndexOutOfBoundsException("您輸入的索引為:"+index+"它的指針長度為:"+a);}}/*** 根據位置獲取指定的節點對象* @param index* @return*/private Node getNode(int index){//判斷當前輸入的指針距離頭或者尾哪個節點近//如果輸入的指針大,從尾部開始找,//如果輸入的指針小,從頭部開始找if (index < (this.size >> 1)){Node node = this.head;//遍歷指針for(int i =0; i < index;i++){//拿到指針處的下一個節點對象賦值nodenode=node.next;}return node;}else {Node node = this.tail;//從尾節點找指針for (int i = this.size-1; i>index; i--){node = node.prev;}return node;}}/*** 獲取元素的長度(個數)* @return*/@Overridepublic int size() {return this.size;}/*** 根據指定指針刪除元素* @param index* @return*/@Overridepublic E remove(int index) {//對index指針進行合法性校驗this.rangeCheck(index);//根據index進行獲取節點對象,判斷從頭刪還是從尾部刪除Node<E> node = this.getNode(index);//獲取index指針處的節點元素數據E item = node.item;//判斷當前節點是否尾頭節點if (node.prev == null){this.head = node.next;}else {//完成當前節點的直接前驅節點和當前節點的直接后繼節點,掛接node.prev.next = node.next;}//當前節點斷掉與它直接前驅點的連接node.prev = null;//當前節點斷掉與他直接后繼節點的連接node.next =null;node.item =null;//長度自減一this.size--;//返回被刪除的節點元素數據return item;}//從頭開始添加元素@Overridepublic void addFirst(E element) {this.linkFirst(element);}//從尾部添加元素@Overridepublic void addLast(E element) {this.linkLast(element);}//在鏈表的頭添加元素private void linkFirst(E element){//獲取頭節點對象Node head = this.head;Node node = new Node(null,element,head);//將新節點定義為頭節點this.head = node;//判斷當前鏈表中是否有節點,如果沒有該節則是頭節點也是尾節點if(this.head == null){this.tail = node;}else {this.head.prev = node;}this.size++;//記錄鏈表長度}/*** 創建節點類* @param <E>*/class Node<E> {private E item;//記錄元素private Node<E> next; // 下一個節點對象private Node<E> prev; // 上一個節點對象Node(Node<E> prev, E element, Node<E> next) {this.item = element;this.next = next;this.prev = prev;}} }
測試
public class MyLinkedMain {public static void main(String[] args) {MyDoubleLinkedList linkedList = new MyDoubleLinkedList();linkedList.add(12);linkedList.add(13);linkedList.add(14);linkedList.add(15);linkedList.add(16);System.out.println(linkedList.get(3));//3是指針,從尾部開始找System.out.println(linkedList.get(4));//4是指針,從尾部開始找System.out.println(linkedList.get(1));//1是指針,從頭部開始找System.out.println(linkedList.size());//獲取linkedList長度System.out.println("刪除前的指針1處的數據"+linkedList.get(1));System.out.println(linkedList.remove(1));System.out.println("刪除后的指針1處的數據"+linkedList.get(1));System.out.println("刪除前的指針0處的數據"+linkedList.get(4));System.out.println(linkedList.remove(4));try {System.out.println("刪除后的指針0處的數據"+linkedList.get(4));}catch (Exception e) {e.printStackTrace();}finally {System.out.println("刪除后的鏈表長度"+linkedList.size());//獲取linkedList長度}} }

總結

以上是生活随笔為你收集整理的数据结构-链表结构的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。