這個是資料結構中最為基礎的兩大結構之一,後面的棧和佇列都會用到單向連結串列作為底層,所以學好了單向連結串列你就成功了一大半了!
public class Node {
private Object data; //存放資料
private Node next; //存放指標
public Node(Object data, Node next) {
this.data = data;
this.next = next;
}
public Node(Object data) {
this.data = data;
this.next=null;
}
public Node() {
this.data=null;
this.next=null;
}
public Object getData() {
return data;
}
public void setData(Object data) {
this.data = data;
}
public Node getNext() {
return next;
}
public void setNext(Node next) {
this.next = next;
}
}
這個節點物件很容易理解就是兩個屬性一個用來存放資料data,另一個存放指標next指向下一個物件資料
public interface MyList {
public void clear(); //讓連結串列為空
public boolean isEmpty(); //判斷連結串列是否為空
public int length(); //返回連結串列中的元素長度
public Object get(int i); //獲得指定索引上的元素
public void insert(int i,Object x)throws Exception; //在指定索引位置上插入指定資料
public void add(Object x) throws Exception; //插入指定資料
public void remove(int i)throws Exception; //刪除指定索引上的元素
public void delete(Object x)throws Exception; //刪除指定元素
public void printList() ; //遍歷連結串列中的所有元素
public int getData(Object x); //獲得指定元素的索引
}
你也可以不寫介面但是寫介面會顯得更專業一點
public class MyLinkedList implements MyList{
private Node header;//頭節點
private int size;//元素個數
public MyLinkedList() {
this.header=new Node(null);
this.size=0;
}
}
這裡的構造方法是為了初始化的作用 , 建立一個新的node物件不給他賦值用來作為一個頭結點 , 這個頭節點不用儲存資料 . 然後初始化size的個數為0.*
這個就是連結串列的基本結構
@Override
public void clear() {
header.setNext(null);
}
@Override
public boolean isEmpty() {
return this.size==0;
}
@Override
public int length() {
return this.size;
}
clear方法 : 直接讓頭節點的下一位指標指向一個空;
isEmpty方法 : 直接返回size屬性是否為0用來判斷該連結串列是否為空
length方法 : 直接返回size的值就為連結串列的有效長度
@Override
public void insert(int i, Object x) throws Exception {
if(i<0||i>=size) {
throw new Exception("索引不合法");
}
Node newNode=new Node(x);
Node temp=header.getNext();
while(temp.getNext()!=null && i>=0) {
temp=temp.getNext();
i--;
}
newNode.setNext(temp.getNext());
temp.setNext(newNode);
size++;
}
@Override
public void add(Object x) throws Exception {
Node newNode=new Node(x);
if(size==0) {
header.setNext(newNode);
}else{
Node temp=header.getNext();
while(temp.getNext()!=null) {
temp=temp.getNext();
}
temp.setNext(newNode);
}
size++;
}
add和insert方法基本思路是一樣的 , 如果指定了索引就通過迴圈找出索引位置的資料在他後面新增新資料 , 然後把指定位置資料的後一個資料跟newNode連線 . 如果沒有指定索引那就簡單了直接回圈到最後一個元素然後接在後面
@Override
public void remove(int i) throws Exception {
if(size==0) {
System.out.println("沒有元素");
}else {
int k=0;
Node temp=header.getNext();
Node prTemp=header;
while(temp.getNext()!=null) {
if(k==i) {
prTemp.setNext(temp.getNext());
}
prTemp=temp;
k++;
temp=temp.getNext();
}
size--;
}
}
@Override
public void delete(Object x) throws Exception {
if(size==0) {
System.out.println("滿了");
}else {
Node temp=header.getNext();
Node prTemp=header;
while(temp.getNext()!=null) {
if(temp.getData()==x) {
prTemp.setNext(temp.getNext());
}
prTemp=temp;
temp=temp.getNext();
}
size--;
}
}
**remove和delete方法都有異曲同工之妙建立了pretemp和temp物件用來儲存指定元素前面一個元素和指定元素 , 刪除操作也很簡單就是通過讓指定元素前後指標繞開他與後面連線 , 就會形成沒有指標指向指定元素從而達到刪除效果 **
@Override
public Object get(int i) {
if(size==0) {
System.out.println("沒元素");
}else {
Node temp=header.getNext();
while(temp.getNext()!=null && i>=0) {
temp=temp.getNext();
i--;
}
return temp.getData();
}
return null;
}
@Override
public int getData(Object x) {
if(size==0) {
System.out.println("無元素");
}else {
int i=0;
Node temp=header.getNext();
while(temp.getNext()!=null) {
if(temp.getData()==x) {
return i;
}
i++;
temp=temp.getNext();
}
}
return -1;
}
get和getData方法都很像通過迴圈獲得了指定位置的資料存入temp中然後 , 用int型別的變數進行計數獲得索引.
@Override
public void printList() {
if(size==0) {
System.out.println("無元素");
}else {
Node temp=header.getNext();
while(temp.getNext()!=null) {
System.out.print(temp.getData()+" , ");
temp=temp.getNext();
}
System.out.println(temp.getData());
}
}
public class MyLinkedList implements MyList{
private Node header;//頭節點
private int size;//元素個數
public MyLinkedList() {
this.header=new Node(null);
this.size=0;
}
@Override
public void clear() {
header.setNext(null);
}
@Override
public boolean isEmpty() {
return this.size==0;
}
@Override
public int length() {
return this.size;
}
@Override
public Object get(int i) {
if(size==0) {
System.out.println("沒元素");
}else {
Node temp=header.getNext();
while(temp.getNext()!=null && i>=0) {
temp=temp.getNext();
i--;
}
return temp.getData();
}
return null;
}
@Override
public void insert(int i, Object x) throws Exception {
if(i<0||i>=size) {
throw new Exception("索引不合法");
}
Node newNode=new Node(x);
Node temp=header.getNext();
while(temp.getNext()!=null && i>=0) {
temp=temp.getNext();
i--;
}
newNode.setNext(temp.getNext());
temp.setNext(newNode);
size++;
}
@Override
public void add(Object x) throws Exception {
Node newNode=new Node(x);
if(size==0) {
header.setNext(newNode);
}else{
Node temp=header.getNext();
while(temp.getNext()!=null) {
temp=temp.getNext();
}
temp.setNext(newNode);
}
size++;
}
@Override
public void remove(int i) throws Exception {
if(size==0) {
System.out.println("滿了");
}else {
int k=0;
Node temp=header.getNext();
Node prTemp=header;
while(temp.getNext()!=null) {
if(k==i) {
prTemp.setNext(temp.getNext());
}
prTemp=temp;
k++;
temp=temp.getNext();
}
size--;
}
}
@Override
public void delete(Object x) throws Exception {
if(size==0) {
System.out.println("無元素");
}else {
Node temp=header.getNext();
Node prTemp=header;
while(temp.getNext()!=null) {
if(temp.getData()==x) {
prTemp.setNext(temp.getNext());
}
prTemp=temp;
temp=temp.getNext();
}
size--;
}
}
@Override
public void printList() {
if(size==0) {
System.out.println("無元素");
}else {
Node temp=header.getNext();
while(temp.getNext()!=null) {
System.out.print(temp.getData()+" , ");
temp=temp.getNext();
}
System.out.println(temp.getData());
}
}
@Override
public int getData(Object x) {
if(size==0) {
System.out.println("無元素");
}else {
int i=0;
Node temp=header.getNext();
while(temp.getNext()!=null) {
if(temp.getData()==x) {
return i;
}
i++;
temp=temp.getNext();
}
}
return -1;
}
}
**小結**
單鏈列表是資料結構中最為基礎的結構我們必須要牢記並且熟練掌握 , 本身不是很難我們需要理解的是temp通過迴圈獲得指定元素 , 還有就是連結串列的刪除和插入的原理 . 一定要熟記