在談順序表之前我們先談一下線性表,顯而易見爲啥叫線性表,就是因爲表中的元素時連續的,而線性表又分爲順序表和鏈表。
這兩者有啥不同呢?
順序表 | 鏈表 |
---|---|
在物理地址上是連續存儲的 | 物理存儲結構非連續 |
可以隨機訪問 | 只能遍歷查找,不支持隨機訪問 |
在中間位置或者表頭添加元素、刪除元素比較噁心 | 任意位置添加、刪除元素的時間複雜度都是O(1) |
擴容的代價比較大 | 插入元素只需要開闢一個新的節點 |
一、順序表
說白了,順序表就是數組,依託於數組進行增刪改查等操作。 順序表又包含:- 靜態順序表:使用定長數組存儲
- 動態順序表:使用動態開闢的數組存儲
想對來說還是動態順序表更好用,更靈活一點,在這裏我實現動態順序表藉助於重新創建一個長度爲原長2倍的新的數組來實現。
import java.io.InputStream;
public class SuquenceTable {
//先創建一個定長爲100的數組
int[] arr = new int[100];
//記錄順序表中真實存儲的元素
int size = 0;
//在指定位置增加元素
public void addElem(int pos,int elem) {
if (pos > arr.length || pos < 0) {
return;
}
if(size >= arr.length) {
relloc();
}
if (pos == size) {
arr[pos] = elem;
size++;
}else {
for (int i = size;i > pos;i--) {
arr[i] = arr[i-1];
}
arr[pos] = elem;
size++;
}
}
//擴容
private void relloc() {
int[] newArr = new int[arr.length * 2];
System.arraycopy(this.arr,0,newArr,0,this.arr.length);
this.arr = newArr;
}
//得到某個位置的元素
public Integer getPos(int pos) {
if (pos < 0) {
System.out.println("該位置沒有元素");
return null;
}else {
return arr[pos];
}
}
//查看是否包含某個元素
public boolean isContains(int key) {
return this.search(key) != -1;
}
public int search(int key) {
for (int i = 0; i < this.arr.length; i++) {
if (key == arr[i]) {
return i;
}
}
return -1;
}
//刪除第一次出現的某個元素
public void remove(int key) {
int pos = search(key);
if (pos == -1) {
return;
}
if (pos == size - 1){
size--;
return;
}
for (int i = pos;i < size - 1;i++) {
this.arr[i] = this.arr[i+1];
}
size--;
return;
}
//得到順序表大小
public int getSize(){
return this.size;
}
//清空順序表
public void clear() {
int[] newArr = new int[this.arr.length];
this.arr = newArr;
size = 0;
}
}
二、鏈表
我實現一下最簡單的無頭單鏈表好了,沒有爲啥,問就是簡單。package LinkList;
class LinkedNode{
int val;
LinkedNode next;
public LinkedNode(int val) {
this.val = val;
}
}
public class LinkedList {
LinkedNode head = null;
//頭插
public void addFirst(int val) {
LinkedNode node = new LinkedNode(val);
if (this.head == null) {
this.head = node;
return;
}
node.next = head;
head = node;
return;
}
//尾插
public void addLast(int val) {
LinkedNode node = new LinkedNode(val);
if (this.head == null) {
head = node;
return;
}
LinkedNode cur = this.head;
while (cur.next != null) {
cur = cur.next;
}
node.next = cur.next;
cur.next = node;
return;
}
//刪除第一次出現的某個元素
public void remove(int val) {
if (this.head == null) {
return;
}
if (this.head.val == val) {
this.head = this.head.next;
return;
}
LinkedNode node = this.head;
LinkedNode cur = null;
while (node.next != null) {
cur = node.next;
if (cur.val == val) {
break;
}
node = node.next;
}
if (cur == null) {
return;
}
node.next = cur.next;
}
//刪除所有出現的某個元素
public void removeAll(int val) {
if (this.head == null) {
return;
}
LinkedNode first = this.head.next;
LinkedNode slow = head;
while (first != null ) {
if(first.val == val) {
slow.next = first.next;
first = first.next;
}else {
first = first.next;
slow = slow.next;
}
}
if (this.head.val == val) {
this.head = this.head.next;
}
}
/*反轉一個鏈表*/
private void reversrList(LinkedNode head) {
//鏈表爲空或只有一個元素就返回
if (head == null || head.next == null) {
return;
}
LinkedNode newHead = null;
LinkedNode newTail = newHead;
LinkedNode cur = head;
while (cur!= null) {
LinkedNode next = cur.next;
if (next == null) {
newHead = cur;
break;
}
cur.next = newTail;
newTail = cur;
cur = next;
}
head = newHead;
}
/*合併兩個鏈表*/
public LinkedNode mergeList(LinkedNode h1,LinkedNode h2) {
if (h1 == null) {
return h2;
}
if (h2 == null) {
return h1;
}
LinkedNode newHead = new LinkedNode(0);
LinkedNode newTail = newHead;
LinkedNode prve = h1;
LinkedNode cur = h2;
while (prve != null && cur != null) {
if (prve.val > cur.val) {
newTail.next = new LinkedNode(cur.val);
cur = cur.next;
}else {
newTail.next = new LinkedNode(prve.val);
prve = prve.next;
}
newTail = newTail.next;
}
if (cur == null) {
newTail.next = prve;
}
if (prve == null) {
newTail.next = cur;
}
return newHead.next;
}
/*按給定值分割鏈表*/
public LinkedNode partationList(LinkedNode head,int key) {
if (head == null || head.next == null) {
return head;
}
LinkedNode bigHead = new LinkedNode(0);
LinkedNode bigTail = bigHead;
LinkedNode smallHead = new LinkedNode(0);
LinkedNode samllTail = smallHead;
LinkedNode tmp = head;
while (tmp != null) {
if (tmp.val < key) {
samllTail.next = new LinkedNode(tmp.val);
samllTail = samllTail.next;
}else {
bigTail.next = new LinkedNode(tmp.val);
bigTail = bigTail.next;
}
tmp = tmp.next;
}
samllTail.next = bigHead.next;
return smallHead.next;
}
/*刪除一個已排序鏈表的所有重複元素*/
public LinkedNode deleteDuplication(LinkedNode head) {
if (head == null || head.next == null) {
return head;
}
LinkedNode newHead = new LinkedNode(0);
newHead.next = head;
LinkedNode prve = newHead;
LinkedNode cur = prve.next;
while (cur != null) {
if (cur.val == cur.next.val && cur.next != null) {
while (cur.next != null && cur.val == cur.next.val) {
cur = cur.next;
}
prve.next = cur.next;
}else {
prve = prve.next;
}
cur = cur.next;
}
return newHead.next;
}
public boolean isPalindrome(LinkedNode head) {
if (head == null || head.next == null) {
return true;
}
int steps = getSize(head)/2;
LinkedNode newHead = head;
for (int i = 0;i < steps;i++) {
newHead = newHead.next;
}
LinkedNode cur = newHead;
LinkedNode prve = null;
while (cur != null) {
LinkedNode next = cur.next;
if (next == null) {
newHead = cur;
break;
}
cur.next = prve;
prve = cur;
cur = next;
}
while (newHead != null) {
if (newHead.val != head.val) {
return false;
}
newHead = newHead.next;
head = head.next;
}
return true;
}
public int getSize(LinkedNode head) {
LinkedNode node = head;
int size = 0;
while (node != null) {
node = node.next;
size++;
}
return size;
}
}
鏈表還有好多好多,不過我都還不是很會(- _ -),就不列舉了。