JAVA——顺序表和链表
作者:互联网
在谈顺序表之前我们先谈一下线性表,显而易见为啥叫线性表,就是因为表中的元素时连续的,而线性表又分为顺序表和链表。
这两者有啥不同呢?
顺序表 | 链表 |
---|---|
在物理地址上是连续存储的 | 物理存储结构非连续 |
可以随机访问 | 只能遍历查找,不支持随机访问 |
在中间位置或者表头添加元素、删除元素比较恶心 | 任意位置添加、删除元素的时间复杂度都是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;
}
}
链表还有好多好多,不过我都还不是很会(- _ -),就不列举了。
AN稳 发布了13 篇原创文章 · 获赞 1 · 访问量 206 私信 关注标签:head,顺序,JAVA,cur,val,next,链表,LinkedNode,null 来源: https://blog.csdn.net/qq_42541609/article/details/104482253