Java 無頭雙向迴圈連結串列操作方法
阿新 • • 發佈:2021-01-11
無頭雙向迴圈連結串列
結點物件具有三個域 data next prev,其中data放數值,next指向下一個結點物件,prev指向前一個結點物件。
雙向連結串列示意圖
class ListNode{
private int val;
private ListNode next;
private ListNode prev;
//結點建立方法
public ListNode(int val) {
this.val = val;
}
public int getVal() {
return val;
}
public void setVal(int val) {
this.val = val;
}
public ListNode getNext() {
return next;
}
public void setNext(ListNode next) {
this.next = next;
}
public ListNode getPrev() {
return prev;
}
public void setPrev(ListNode prev) {
this.prev = prev;
}
}
public class DoubleLinkedList {
// LinkedList
public ListNode head;
public ListNode last;
//頭插法
public void addFirst(int data){
ListNode node1 = new ListNode(data);
if(head == null){
head = node1;
last = node1;
}else{
node1.setNext(head);
head.setPrev(node1);
head = node1;
}
}
//尾插法
public void addLast(int data){
ListNode node2 = new ListNode(data);
if(head == null){
head = node2;
last = node2;
}else{
last.setNext(node2);
node2.setPrev(last);
last = node2;
}
}
//獲取雙向連結串列長度
public int getLength(){
ListNode cur = head;
int count = 0;
while(cur != null){
cur = cur.getNext();
count++;
}
return count;
}
//任意位置插入,第一個資料結點為0號下標
public void addIndex(int index,int data){
if(index < 0 || index > getLength()){
return ;
}
if(index == 0){
addFirst(data);
return ;
}
if(index == getLength()){
addLast(data);
return ;
}
//定義cur為插入結點的後繼
ListNode cur = head;
while(index != 0){ //走index步
cur = cur.getNext();
index--;
}
ListNode node3 = new ListNode(data);
cur.getPrev().setNext(node3);
node3.setNext(cur);
node3.setPrev(cur.getPrev());
cur.setPrev(node3);
}
//判斷雙向連結串列是否包含關鍵字key
public boolean contains(int key){
if(head == null){
return false;
}
ListNode cur = head;
while(cur != null){
if(cur.getVal() == key){
return true;
}
cur = cur.getNext();
}
return false;
}
//返回雙向連結串列關鍵字為key的結點
public ListNode findNode(int key){
if(head == null){
return null;
}
ListNode cur = head;
while(cur != null){
if(cur.getVal() == key){
return cur;
}
cur = cur.getNext();
}
return null;
}
//刪除第一次出現關鍵字為key的結點
public void remove(int key){
ListNode cur = findNode(key); //尋找關鍵字為key的結點
//表明刪除的結點為空,沒有值關鍵字為key的結點
if(cur == null){
return ;
}
//表明刪除的結點為頭結點
if(cur == head){
head.getNext().setPrev(null);
head = head.getNext();
return ;
}
//表明刪除的結點為尾結點
if(cur == last){
last.getPrev().setNext(null);
last = last.getPrev();
return ;
}
cur.getPrev().setNext(cur.getNext());
cur.getNext().setPrev(cur.getPrev());
}
//第二種刪除方法 無需定義額外的方法
public void remove2(int key){
ListNode cur = head;
while(cur != null){
//表頭的值就是我們要刪除的關鍵字
if(cur.getVal() == key){
if(cur == head) {
head.getNext().setPrev(null);
head = head.getNext();
return ;
}else{
cur.getPrev().setNext(cur.getNext());
//此時判斷cur是不是倒數第二結點和尾結點
if(cur.getNext() != null){
cur.getNext().setPrev(cur.getPrev());
//
}else{
last = last.getPrev();
}
return ;
}
//只放一個return ;在這裡也是沒問題的
// 這裡的else可不要
}else{
cur = cur.getNext();
}
//剛開始return錯放在這裡 導致走一次就return出去 不能再繼續下去
}
return ;
}
//刪除關鍵字為key的所有的結點
public void remove3(int key){
ListNode cur = head;
while(cur != null){
//表頭的值就是我們要刪除的關鍵字
if(cur.getVal() == key){
if(cur == head) {
head.getNext().setPrev(null);
head = head.getNext();
}else if(cur == last){
cur.getPrev().setNext(null);
last = last.getPrev();
}else{
cur.getPrev().setNext(cur.getNext());
cur.getNext().setPrev(cur.getPrev());
}
}
cur = cur.getNext();
//剛開始return錯放在這裡 導致走一次就return出去 不能再繼續下去
}
return ;
}
//清空連結串列
//暴力方式
public void clear(){
head = null;
last = null;
}
//溫柔方式
public void clear1(){
ListNode cur = head;
while(cur != null){
//定義當前結點的下一個結點
ListNode curNext = cur.getNext();
cur.setNext(null);
cur.setPrev(null);
cur = curNext;
}
head = null;
last = null;
}