單向循環鏈表
前面爲了說明方便,有些是用的貼圖,由於有些圖片較大形成擠壓,看不清點擊看原圖即可,源碼會在後面給出,話不多說,開始吧!
- 節點類Node
/**
* @author AmVilCresx
* 節點類
*/
public class Node {
Object element; //數據域
Node next; // 後繼指針域
Node previor;// 前驅指針域
//非頭結點的構造方法
public Node(Object element) {
this.element = element;
}
}
插入鏈表的第一個元素
在尾部插入節點元素
- 在頭部插入節點元素
在指定位置插入元素節點
刪除指定位置的節點
刪除給定的元素節點(註釋做了簡單說明,其它操作跟上面刪除類似)
- 單向循環鏈表源碼
複製粘貼開發工具,修改你自己的包名即可運行
public class Node {
Object element; //數據域
Node next; // 後繼指針域
Node previor;// 前驅指針域
//非頭結點的構造方法
public Node(Object element) {
this.element = element;
}
}
------------------------分割線------------------------------------
package com.avc.link;
/**
* @author AmVilCresx
* 模擬單向循環鏈表
* */
public class CycleLinkList{
Node head; //頭指針
Node rear; //尾節點
Node currentPrior; ////當前節點的前一個節點,下面的刪除和插入要用
int size; //節點個數
/**
* 對空鏈表第一個節點進行插入
* */
private void insertFirstNode(Node node) {
head = node; //頭指針指向node
rear = head; // 尾指針指向head
head.next = rear; //鏈接成環狀
size++; //長度+1
}
/**
* 在末尾插入
* */
public void insertRear(Node node) {
if(head == null) {
insertFirstNode(node); // 插入鏈表的第一個元素
}else {
node.next = rear.next; //將帶插入節點的next指向原鏈表rear的next;
rear.next = node; // 將原鏈表的rear的next指向node
rear = node; // 改變rear的指向 爲node
size++; //長度+1
}
}
/**
* 頭插法
* 頭插其實就是和末尾插入一樣的,只不過尾插改變的是尾指針,頭指針不變,頭插改變頭指針,尾指針不變
* */
public void insertHead(Node node) {
if(head == null) {
insertFirstNode(node);
}else {
node.next = rear.next;
rear.next=node;
head=node; // 此處改變的是頭指針head的指向
size++;
}
}
/**
* 獲取節點
* */
public Node get(int index){
Node tmp = head;
int j=0;
if(index<0 || index>size-1) {
return null;
}
while(j!=index) {
tmp = tmp.next;
j++;
}
return tmp;
}
/**
* 定位到操作節點的前一個位置
* */
public void getLoation(int index) {
currentPrior = head;
int j=0;
while(j<index-1) {//找到要插入的位置前一個位置
currentPrior = currentPrior.next;
j++;
}
if(index==0) { //如果是第一個節點,則它的前一個節點就是rear節點,上面的while沒處理這種情況
currentPrior=rear; //手動賦值
head=head.next; //注意:一定要將head指向下一個節點,不然get的時候會出錯
}
}
/**
* 在這指定位置進行插入
* */
public void insertAnyWhere(int index,Node node) {
if(index<0 || index > size) {
throw new RuntimeException("參數非法");
}
if(index == 0) { //第一個位置,說明是頭插
this.insertHead(node);
}else if(index == size) { //最後一個位置,說明是,尾插
this.insertRear(node);
}else {
getLoation(index); //定位到index的前一個位置
node.next = currentPrior.next; // 將帶插入節點的next指向當前節點(也就是當前節點的前一個節點的下一個節點)
currentPrior.next=node; // 將前一個節點的next指向node,完成連接
size++; // 長度+1
}
}
/**
* 刪除指定位置的節點
* */
public Node delete(int index) {
if(index<0 || index>size-1)
throw new RuntimeException("參數非法");
if(isEmpty()) {
throw new RuntimeException("鏈表爲空,操作失敗");
}
Node delNode = null;
getLoation(index); //定位到index的前一個位置
delNode = currentPrior.next; //待刪除的節點(當前節點)
currentPrior.next=delNode.next; // 將當前節點的前驅節點的next指針指向當前節點的next域
size--; //長度 -1
return delNode;
}
/**
* 刪除給定的節點,這裏爲了測試方便,默認值相同則是相同的節點,並且不存在element相同的節點
* */
public Node deleteByNode(Node node) {
Node delNode= null;
if(isEmpty()) {
throw new RuntimeException("鏈表爲空,操作失敗");
}
if(size==1 && node.element == head.element) {
delete(0);
head=null;
return node;
}
Node tmp = head; //臨時指針變量
int count=size;
while(count>0 && node.element!= tmp.next.element) {
// 如果小於count,沒走完一圈 或者下個節點的值不等於給定節點的值
count--;
tmp = tmp.next;
}
if(count==0) {
throw new RuntimeException("元素不存在,無法刪除");
}else {
delNode = tmp.next;
if(delNode==head) { // 判斷一下,不然get會出錯
head=delNode.next;
}
if(tmp.next==rear) {
rear=tmp;
}
tmp.next=delNode.next; // 改變指針指向
size--;
}
return delNode;
}
//鏈表大小
public int size() {
return this.size;
}
/**
* 判斷鏈表是否爲空
* */
public boolean isEmpty() {
return size==0;
}
public static void main(String[] args) {
CycleLinkList list = new CycleLinkList();
/*list.insertRear(new Node(1));
list.insertRear(new Node(2));
list.insertRear(new Node(3));
System.out.println(list.get(1).getElement());*/
list.insertHead(new Node(1));
list.insertHead(new Node(2));
list.insertHead(new Node(3));
list.insertHead(new Node(4));
Node ist = new Node(6);
list.insertRear(ist);
// list.insertAnyWhere(1, new Node("insrt"));
/*System.out.println(list.get(1).element);
System.out.println("size----"+list.size());
list.delete(1);
System.out.println("size----"+list.size());
System.out.println(list.get(1).element);
System.out.println(list.get(1).next.element);*/
System.out.println("size----"+list.size());
System.out.println(list.get(3).element);
System.out.println(list.deleteByNode(ist).element);
System.out.println("size----"+list.size());
System.out.println(list.get(3).element);
}
}
雙向循環鏈表
在尾部插入節點元素
在頭部插入元素節點
在指定的位置插入節點
刪除指定位置的節點元素
刪除給定的節點元素
- 雙向循環鏈表源碼
package com.avc.link;
/**
* @author AmVilCresx
* 模擬雙向循環鏈表
*
*/
public class CycleBothWayLinkList {
Node head; //頭指針
Node rear; //尾節點
Node current; //當前節點,下面的刪除和插入要用
int size=0; //節點個數
/**
* 插入整個鏈表的第一個節點
* */
private void insertFirstNode(Node node ) {
head=node;
rear=head;
head.next=rear;
head.previor=rear;// 形成雙向環狀
size++;
}
/**
* 尾插法
* */
public void insertRear(Node node) {
if(head == null) {
insertFirstNode(node);
}else {
node.next=rear.next; // 將帶插入節點node的next指向rear的next
node.previor=rear; // 將node的前驅指向rear
rear.next.previor=node; //將rear的next的前驅指向node
rear.next=node; //將rear的next指向node
rear=node; //將rear設置爲node
size++;
}
}
/**
* 頭插法
* */
public void insertHead(Node node) {
if(head == null) {
insertFirstNode(node);
}else {
node.next=rear.next; // 將帶插入節點node的next指向rear的next
node.previor=rear; //將node的前驅指向rear
rear.next.previor=node; //將原來rear的next節點的前驅設置爲node
rear.next=node; //則rear的next指向node
head = node; // 改變head的指向
size++;
}
}
/**
* 在任意位置插入
* */
public void insertAnyWhere(int index, Node node) {
if(index<0 || index>size) {
throw new RuntimeException("參數非法!");
}
if(index ==0) {
insertHead(node);
}else if(index==size) {
insertRear(node);
}else {
getLoation(index); // 因爲是雙向鏈表,所以直接定位到要操作的節點
node.next = current; //將待插入節點的next指向當期節點
node.previor=current.previor; //將node的前驅節點設置爲當前節點的前驅節點
current.previor.next=node; // 再講當前節點的前驅的next指向node
current.previor=node; // 再將當前節點的前驅節點設置爲node
size++;
}
}
/**
* 刪除指定位置的節點
* */
public Node deleteNode(int index) {
if(index<0 || index>size-1)
throw new RuntimeException("參數非法");
if(isEmpty()) {
throw new RuntimeException("鏈表爲空,操作失敗");
}
getLoation(index);//找到要插入的位置的當前節點(這裏也可以找要操作的節點的前一個節點,因爲這裏有前驅指針,可不必)
Node delNode = current;
current.previor.next=current.next;
current.next.previor=current.previor;
size--;
return delNode;
}
/**
* 刪除給定的節點,這裏爲了測試方便,默認值相同則是相同的節點,並且不存在element相同的節點
* */
public Node deleteByGiveNode(Node node) {
Node delNode= null;
if(isEmpty()) {
throw new RuntimeException("鏈表爲空,操作失敗");
}
if(size==1 && node.element == head.element) {
deleteNode(0);
head=null;
return node;
}
Node tmp = head;
int count=size;
while(count>0 && tmp.element != node.element) {
count--;
tmp=tmp.next;
}
if(count==0) {
throw new RuntimeException("元素不存在,無法刪除");
}else {
delNode = tmp;
if(delNode==head) {
head=delNode.next;
}
if(delNode==rear) {
rear=delNode.previor;
}
tmp.previor.next=tmp.next;
tmp.next.previor=tmp.previor;
size--;
}
return delNode;
}
//定位到指定位置
public void getLoation(int index) {
current = head;
int j=0;
while(j<index) {//找到要插入的位置前一個位置
current = current.next;
j++;
}
if(index ==0) {
head = current.next; //改變head的指向
}
}
/**
* 獲取節點
* */
public Node get(int index){
Node tmp = head;
int j=0;
if(index<0 || index>size-1) {
return null;
}
while(j!=index) {
tmp = tmp.next;
j++;
}
return tmp;
}
public boolean isEmpty() {
return size==0;
}
//鏈表大小
public int size() {
return this.size;
}
/**
* main函數測試
* */
public static void main(String[] args) {
CycleBothWayLinkList cyl = new CycleBothWayLinkList();
cyl.insertHead(new Node(1));
cyl.insertHead(new Node(2));
cyl.insertHead(new Node(3));
cyl.insertHead(new Node(4));
System.out.println("前驅:"+cyl.get(0).previor.element);
System.out.println("自身:"+cyl.get(0).element);
System.out.println("後繼:"+cyl.get(0).next.element);
System.out.println("---------------");
cyl.insertAnyWhere(0, new Node("insrt"));
System.out.println("前驅:"+cyl.get(0).previor.element);
System.out.println("自身:"+cyl.get(0).element);
System.out.println("後繼:"+cyl.get(0).next.element);
System.out.println("---------------");
cyl.deleteNode(0);
System.out.println("前驅:"+cyl.get(0).previor.element);
System.out.println("自身:"+cyl.get(0).element);
System.out.println("後繼:"+cyl.get(0).next.element);
}
}
有問題請大家留言,批評指正!共勉!!!