线性表
线性表是n个具有相同特性的数据元素的有限序列。 线性表是一种在实际中广泛使用的数据结构,常见的线性表:顺序表、链表、栈、队列、字符串…
线性表在逻辑上是线性结构,也就说是连续的一条直线。但是在物理结构上并不一定是连续的,线性表在物理上存储时,通常以数组和链式结构的形式存储
顺序表
顺序表是用一段物理地址连续的存储单元依次存储数据元素的线性结构,一般情况下采用数组存储。在数组上完成数据的增删查改
示例代码:
import java.util.Arrays;
public class MyArrayList {
private int[] elem;
private int usedSize;
public MyArrayList(){
this.elem = new int[5];
}
public MyArrayList(int capacity){
this.elem = new int[capacity];
}
// 打印顺序表
public void display() {
for (int i = 0; i < usedSize; i++) {
System.out.print(this.elem[i]+" ");
}
System.out.println();
}
//判断是否已满
public Boolean isFull(){
if(this.elem.length==this.usedSize){
return true;
}
return false;
}
//调整大小
public void resize(){
this.elem=Arrays.copyOf(this.elem,2*this.elem.length);
}
// 在 pos 位置新增元素
public void add(int pos, int data) {
if (isFull()) {
resize();
}
if (pos < 0 || pos >this.usedSize) {
System.out.println("pos位置不合法!");
return;
}
for (int i = this.usedSize-1; i >= pos ;i--) {
this.elem[i+1] = this.elem[i];
}
this.elem[pos] = data;
this.usedSize++;
}
// 判定是否包含某个元素
public boolean contains(int toFind) {
for (int i = 0; i < this.usedSize; i++) {
if (this.elem[i]==toFind)
return true;
}
return false;
}
// 查找某个元素对应的位置
public int search(int toFind) {
for (int i = 0; i < usedSize; i++) {
if(this.elem[i]==toFind)
return i;
}
return -1;
}
// 获取 int 位置的元素
public int getPos(int pos) {
if (pos < 0 || pos >= this.usedSize) {
return -1;
}
return this.elem[pos];
}
// 给 pos 位置的元素设为 value
public void setPos(int pos, int value) {
if(pos<0||pos>=this.usedSize){
return ;
}
this.elem[pos]=value;
}
//删除第一次出现的关键字key
public void remove(int toRemove) {
int index = search(toRemove);
if(index == -1) {
System.out.println("未找到");
return;
}
for(int i = index;i < this.usedSize-1;i++) {
this.elem[i] = this.elem[i+1];
}
this.usedSize--;
}
// 获取顺序表长度
public int size() {
return this.usedSize;
}
// 清空顺序表
public void clear() {
this.usedSize=0;
System.out.println("已清空!");
}
}
链表
链表是一种物理存储结构上非连续存储结构,数据元素的逻辑顺序是通过链表中的引用链接次序实现的
单向链表:
class Node {
public int data;
public Node next;
public Node(){
}
public Node head;
public Node(int data){
this.data = data;
}
}
public class MyLinkList {
public Node head;
public Node headA;
public Node headB;
//输出
public void display() {
Node cur = this.head;
while (cur != null) {
System.out.print(cur.data + " ");
cur = cur.next;
}
System.out.println();
}
//任意位置输出
public void display(Node newHead) {
Node cur = newHead;
while (cur != null) {
System.out.print(cur.data + " ");
cur = cur.next;
}
System.out.println();
}
//得到长度
public int size() {
Node cur = this.head;
int count = 0;
while (cur != null) {
count++;
cur = cur.next;
}
return count;
}
public int size(Node head) {
Node cur = head;
int count = 0;
while (cur != null) {
count++;
cur = cur.next;
}
return count;
}
//头插法
public void addFirst(int data) {
Node cur = new Node(data);
cur.next = this.head;
this.head = cur;
}
//尾插法
public void addLast(int data) {
Node node = new Node(data);
if (this.head == null) {
this.head = node;
} else {
Node cur = this.head;
while (cur.next != null) {
cur = cur.next;
}
cur.next = node;
}
}
public void addLastA(int data) {
Node node = new Node(data);
if (this.headA == null) {
this.headA = node;
} else {
Node cur = this.headA;
while (cur.next != null) {
cur = cur.next;
}
cur.next = node;
}
}
public void addLastB(int data) {
Node node = new Node(data);
if (this.headB == null) {
this.headB = node;
} else {
Node cur = this.headB;
while (cur.next != null) {
cur = cur.next;
}
cur.next = node;
}
}
//找最后一个
public Node findLastNode() {
if (this.head == null) {
System.out.println("链表为空!");
}
Node cur = this.head;
while (cur.next != null) {
cur = cur.next;
}
return cur;
}
//找倒数第二个
public Node findTLastNode() {
if (this.head == null) {
System.out.println("链表为空!");
}
Node cur = this.head;
while (cur.next.next != null) {
cur = cur.next;
}
return cur;
}
//找第n个
public Node findNode(int n) {
Node cur = this.head;
if (this.head == null || n <= 0 || n > this.size()) {
return null;
}
int count = 0;
while (count != n) {
cur = cur.next;
count++;
}
return cur;
}
//找key是否存在
public boolean contains(int key) {
Node cur = this.head;
if (cur == null) {
System.out.println("链表为空!");
} else {
cur = cur.next;
}
if (cur.data == key)
return true;
else
return false;
}
//下标为index的节点
public Node findIndex(int index) {
if (index < 0 || index > size()) {
System.out.println("index不合法!");
return null;
}
Node cur = this.head;
int count = 0;
while (count != index) {
count++;
cur = cur.next;
}
return cur;
}
//任意位置插入,第一个数据节点为0号下标
public void addIndex(int index, int data) {
Node node = new Node(data);
if (index < 0 || index > size()) {
System.out.println("index不合法!");
}
if (index == 0) {
addFirst(data);
}
if (index == size()) {
addLast(data);
} else {
Node cur = findIndex(index);
node.next = cur.next;
cur.next = node;
}
}
//找key的前驱
public Node searchPrev(int key) {
Node cur = this.head;
if (cur == null) {
return null;
}
while (cur.next != null) {
if (cur.next.data == key) {
return cur;
}
cur = cur.next;
}
return null;
}
//删除第一次出现关键字为key的节点
public void remove(int key) {
if (this.head == null) {
return;
}
if (this.head.data == key) {
this.head = this.head.next;
return;
}
Node prev = searchPrev(key);
if (prev == null) {
System.out.println("无当前key前驱");
} else {
prev.next = prev.next.next;
}
}
//删除所有值为key的节点
public void removeAllKey(int key) {
Node prev = this.head;
Node cur = prev.next;
while (cur != null) {
if (cur.data == key) {
prev.next = cur.next;
cur = cur.next;
} else {
prev = cur;
cur = cur.next;
}
}
if (this.head.data == key) {
this.head = this.head.next;
}
}
//删除所有值为key的节点2
public void removeKey(int key) {
Node p;
Node q = null;
for (p = this.head; p != null && p.data != key; q = p, p = p.next) ;
if (p != null) {
if (p == this.head) {
this.head = this.head.next;
} else {
q.next = p.next;
}
}
}
//反转链表
public Node reverseList() {
Node cur = this.head;//cur 代表当前要反转的节点
Node prev = null;//prev 代表当前需要反转的节点的前驱
Node newHead = null;
while (cur != null) {
Node curNext = cur.next;//curNext 代表当前需要反转的下一个节点
if (curNext == null) {
newHead = cur;
}
cur.next = prev;
prev = cur;
cur = curNext;
}
this.head = newHead;
return newHead;
}
//反转链表头插法
public Node reverseList2() {
Node prev = null;
while (head != null) {
Node cur = head;
head = head.next;
cur.next = prev;
prev = cur;
}
this.head = prev;
return prev;
}
//找到中间节点
//slow一个一个跑,fast两个两个跑
public Node middleNode() {
Node fast = this.head;
Node slow = this.head;
while (fast != null && fast.next != null) {
fast = fast.next.next;
slow = slow.next;
}
return slow;
}
//倒数第K个
public Node findKthToTail(int k) {
if (head == null || k <= 0) {
return null;
}
Node fast = this.head;
Node slow = this.head;
while (k - 1 != 0) {
if (fast.next != null) {
fast = fast.next;
k--;
} else {
return null;//k过大
}
}
while (fast.next != null) {
fast = fast.next;
slow = slow.next;
}
return slow;
}
//
//将两个升序合并为一个
public Node mergeTwoLists(Node headA, Node headB) {
Node newHead = new Node();
Node tmp = newHead;
while (headA != null && headB != null) {
if (headA.data < headB.data) {
tmp.next = headA;
headA = headA.next;
} else {
tmp.next = headB;
headB = headB.next;
}
tmp = tmp.next;
}
//代码走到这里肯定是一个为空 一个不为空
if (headA != null) {
tmp.next = headA;
}
if (headB != null) {
tmp.next = headB;
}
return newHead.next;
}
//删除重复
public Node deleteDuplication(Node pHead) {
if (pHead == null) {
return null;
}
Node newHead = new Node();
Node tmp = newHead;
Node cur = pHead;
while (cur != null) {
if (cur.next != null && cur.data == cur.next.data) {
while (cur.next != null && cur.data == cur.next.data) {
cur = cur.next;
}
cur = cur.next;
} else {
tmp.next = cur;
tmp = tmp.next;
cur = cur.next;
}
}
tmp.next = null;
return newHead.next;
}
//小于K在前,大于K在后
public Node part(Node pHead, int x) {
if (pHead == null) {
return null;
}
Node bs = null;
Node be = null;
Node as = null;
Node ae = null;
Node cur = pHead;
while (cur != null) {
if (cur.data < x) {
if (bs == null) {
bs = cur;
be = cur;
} else {
be.next = cur;
be = be.next;
}
} else {
if (as == null) {
as = cur;
ae = cur;
} else {
ae.next = cur;
ae = ae.next;
}
}
cur = cur.next;
}
if (bs == null) {
return as;
}
be.next = as;
if (as != null) {
ae.next = null;
}
return bs;
}
//链表的回文结构。
public boolean palindromeLink() {
Node be = this.head;
Node prev = middleNode();
Node cur = prev.next;
while (cur != null) {
Node curNext = cur.next;
cur.next = prev;
prev = cur;
cur = curNext;
}
while (be != prev) {
if (be.data != prev.data) {
return false;
}
be = be.next;
prev = prev.next;
if (be.next == prev) {
return true;
}
}
return true;
}
//输入两个链表,找出它们的第一个公共结点。
public Node commonNode(Node headA, Node headB) {
Node ll = headA;
Node ls = headB;
if (ll == null || ls == null) {
return null;
}
int lenA = size(headA);
int lenB = size(headB);
int len = lenA - lenB;
if (len < 0) {
ll = headB;
ls = headA;
len = -len;
}
while (len != 0) {
ll = ll.next;
len--;
}
if (ll != ls) {
ll = ll.next;
ls = ls.next;
}
return ls.next;
}
//给定一个链表,判断链表中是否有环。
public boolean hasRing() {
if (this.head == null) {
return false;
}
Node fast = this.head;
Node slow = this.head;
while (fast != null && fast.next != null) {
fast = fast.next.next;
slow = slow.next;
if (fast == slow) {
break;
}
}
if (fast == null || fast.next == null) {
return false;
}
return true;
}
//给定一个链表,返回链表开始入环的第一个节点。 如果链表无环,则返回 null
public Node findRing() {
if (this.head == null) {
return null;
}
Node fast = this.head;
Node slow = this.head;
while (fast != null && fast.next != null) {
fast = fast.next.next;
slow = slow.next;
if (fast == slow) {
break;
}
}
if (fast == null || fast.next == null) {
return null;
}
slow = this.head;
while (fast != slow) {
slow = slow.next;
fast = fast.next;
}
return fast;
}
//删除链表中间key节点 O(1)
public void delNode(int key) {
Node cur = this.head;
while (cur.data != key){
cur = cur.next;
}
cur.data = cur.next.data;
cur.next = cur.next.next;
}
//清空
public void clear(){
this.head=null;
System.out.println("null");
}
}
双向链表:
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 DoubleLinkList {
private ListNode head;
private ListNode last;
//打印
public void display() {
ListNode cur = this.head;
while(cur !=null) {
System.out.print(cur.getVal()+" ");
cur = cur.getNext();
}
System.out.println();
}
//得到单链表的长度
public int size() {
ListNode cur = this.head;
int count =0;
while (cur !=null) {
count++;
cur =cur.getNext();
}
return count;
}
//头插
public void addFirst(int data) {
ListNode node = new ListNode(data);
if(this.head == null) {
this.head = node;
this.last = node;
}else{
node.setNext(this.head);
this.head.setPrev(node);
this.head = node;
}
}
//尾插
public void addLast(int data) {
ListNode node = new ListNode(data);
if(this.head == null) {
this.head = node;
this.last = node;
}else{
this.last.setNext(node);
node.setPrev(this.last);
this.last = node;
}
}
//任意位置插入,第一个数据节点为0号下标
public void addIndex(int index,int data) {
if(index < 0||index > size()) {
return;
}
if(index == 0){
addFirst(data);
return;
}
if(index == size()) {
addLast(data);
return;
}
ListNode cur =this.head;
while (index != 0) {
cur = cur.getNext();
index--;
}
ListNode node = new ListNode(data);
node.setNext(cur);
node.setPrev(cur.getPrev());
cur.getPrev().setNext(node);
cur.setPrev(node);
}
//查找是否包含关键字key是否在单链表当中
public boolean contains(int key) {
ListNode cur = this.head;
while (cur != null) {
if (cur.getVal() == key) {
return true;
}
cur = cur.getNext();
}
return false;
}
//删除第一次出现关键字为key的节点
public void remove(int key) {
ListNode cur = this.head;
while (cur != null) {
if (cur.getVal() == key) {
if (cur == this.head) {
this.head = this.head.getNext();
this.head.setPrev(null);
} else if (cur == this.last) {
cur.getPrev().setNext(null);
this.last = this.last.getPrev();
} else {
cur.getPrev().setNext(cur.getNext());
cur.getNext().setPrev(cur.getPrev());
}
return;
}
cur = cur.getNext();
}
}
//删除所有值为key的节点
public void removeAllKey(int key) {
ListNode cur = this.head;
while (cur != null) {
if (cur.getVal() == key) {
if (cur == this.head) {
this.head = this.head.getNext();
if(this.head != null) {
this.head.setPrev(null);
}
} else if (cur == this.last) {
cur.getPrev().setNext(null);
this.last = this.last.getPrev();
} else {
cur.getPrev().setNext(cur.getNext());
cur.getNext().setPrev(cur.getPrev());
}
}
cur = cur.getNext();
}
}
//清空
public void clear() {
this.head = null;
this.last = null;
System.out.println("null");
}
}