Java集合框架:
1. 顺序表
顺序表是用一段
物理地址连续
的存储单元依次存储数据元素的线性结构,一般情况下采用数组存储。在数组上完成 数据的增删查改。
1.1 自己构造AarrayList
package demo1;
import java.util.Arrays;
public class MyArraylist {
public int[] elem;
public int usedSize;//0
//默认容量
private static final int DEFAULT_SIZE = 10;
public static void main(String[] args) {
}
public MyArraylist() {
this.elem = new int[DEFAULT_SIZE];
}
/**
* 打印顺序表:
* 根据usedSize判断即可
*/
public void display() {
for(int i = 0; i < this.usedSize; i++){
System.out.print(this.elem[i] + " ");
}
System.out.println();
}
// 新增元素,默认在数组最后新增
public void add(int data) {
if (isFull()) {
this.elem = Arrays.copyOf(this.elem, 2 * this.elem.length);
}
this.elem[usedSize] = data;
this.usedSize++;
}
/**
* 判断当前的顺序表是不是满的!
*
* @return true:满 false代表空
*/
public boolean isFull() {
return this.usedSize == this.elem.length;
}
private void checkPosInAdd(int pos) throws checkPosInAddEcxption{
if(pos < 0 || pos > usedSize){
System.out.println("不合法!!!");
throw new checkPosInAddEcxption("下标异常" + pos);
}
}
// 在 pos 位置新增元素
public void add(int pos, int data) {
try {
checkPosInAdd(pos);
} catch (checkPosInAddEcxption e){
e.printStackTrace();
return;
}
for(int i = usedSize -1 ; i >= pos; i++){
elem[i+1] = elem[i];
}
elem[pos] = data;
usedSize++;
}
// 判定是否包含某个元素
public boolean contains(int toFind) {
if(isEmpty()){
return false;
}
for(int i = 0; i < usedSize; i++){
if(elem[i] == toFind){
return true;
}
}
return false;
}
// 查找某个元素对应的位置
public int indexOf(int toFind) {
if(isEmpty()){
return -1;
}
for(int i = 0; i < usedSize; i++){
if(elem[i] == toFind){
return i;
}
}
return -1;
}
// 获取 pos 位置的元素
public int get(int pos) throws EmptyIndexOnExcption {
checkPosInAdd(pos);
if(isEmpty()) {
throw new EmptyIndexOnExcption("数组为空");
}
return elem[pos];
}
private boolean isEmpty() {
return usedSize == 0;
}
// 给 pos 位置的元素设为【更新为】 value
public void set(int pos, int value) throws EmptyIndexOnExcption {
checkPosInAdd(pos);
if(isEmpty()){
throw new EmptyIndexOnExcption("为空point");
}
elem[pos] = value;
}
/**
* 删除第一次出现的关键字key
*
* @param key
*/
public void remove(int key) {
int index = indexOf(key);
if(index == -1){
System.out.println("没有该数字");
return;
}
for(int i = index; i < usedSize - 1; i++){
elem[i] = elem[i+1];
}
usedSize--;
}
// 获取顺序表长度
public int size() {
return usedSize;
}
// 清空顺序表
public void clear() {
this.usedSize = 0;
}
}
这个就是顺序表自己构造主要分为十二个函数,顺序表主要由数组来进行完成,并自己定义了内存大小,接着来判断是否符合那些函数的操作。
2. 链表
2.1 自己改造单链表MySingleList
package Demo;
public class MySingleList implements IList {
static class ListNode {
public int val;
public ListNode next;
public ListNode(int val) {
this.val = val;
}
}
public ListNode head;
public void CreatLine() {
ListNode node1 = new ListNode(12);
ListNode node2 = new ListNode(23);
ListNode node3 = new ListNode(34);
ListNode node4 = new ListNode(45);
ListNode node5 = new ListNode(56);
node1.next = node2;
node2.next = node3;
node3.next = node4;
node4.next = node5;
this.head = node1;
}
@Override
public void addFirst(int data) {
ListNode node = new ListNode(data);
if (head == null) {
head = node;
} else {
node.next = head;
head = node;
}
}
@Override
public void addLast(int data) {
ListNode nodeLast = new ListNode(data);
ListNode cur = head;
if (head == null) {
head = nodeLast;
return;
} else {
while (cur.next != null) {
cur = cur.next;
}
cur.next = nodeLast;
}
}
//任意位置插入,第一个数据节点为0号下标
@Override
public void addIndex(int index, int data) throws IsIndexEcxption {
isIndexNormal(index);
isEmpty();
ListNode node = new ListNode(data);
ListNode cur = head;
int count = 0;
if (index == size()) {
addLast(data);
return;
}
if (index == 0) {
addFirst(data);
return;
}
while (cur != null) {
if (index - 1 != count) {
count++;
} else {
node.next = cur.next;
cur.next = node;
return;
}
cur = cur.next;
}
}
private void isIndexNormal(int pos) {
if (pos < 0 || pos > size()) {
throw new IsIndexEcxption("用户使用下标错误" + pos);
}
}
@Override
public boolean contains(int key) {
ListNode cur = head;
isEmpty();
while (cur != null) {
if (cur.val == key) {
return true;
} else {
cur = cur.next;
}
}
return false;
}
private void isEmpty() throws IsEmptyExcption {
if (head == null) {
throw new IsEmptyExcption("链表为空");
}
}
@Override
public void remove(int key) {
isEmpty();
if (head.val == key) {
head = head.next;
return;
}
ListNode cur = findPrec(key);
if (cur == null) {
System.out.println("没有该函数");
return;
}
ListNode del = cur.next;
cur.next = del.next;
}
private ListNode findPrec(int key) {
ListNode cur = head;
while (cur.next != null) {
if (cur.next.val == key) {
return cur;
}
cur = cur.next;
}
return null;
}
@Override
public void removeAllKey(int key) {
isEmpty();
ListNode pre = head;
ListNode cur = head.next;
while (cur != null) {
if (cur.val == key) {
pre.next = cur.next;
cur = cur.next;
} else {
pre = cur;
cur = cur.next;
}
}
if (head.val == key) {
head = head.next;
}
}
@Override
public int size() {
int count = 0;
ListNode cur = head;
if (head == null) {
return 0;
}
while (cur != null) {
count++;
cur = cur.next;
}
return count;
}
@Override
public void display() {
ListNode cur = head;
isEmpty();
while (cur != null) {
System.out.print(cur.val + " ");
cur = cur.next;
}
System.out.println();
}
@Override
public void clear() {
head = null;
}
public ListNode reverseList() {
if (head == null) {
return null;
}
if (head.next == null) {
return head;
}
ListNode cur = head.next;
head.next = null;
while (cur != null) {
ListNode curNext = cur.next;
cur.next = head;
head = cur;
cur = curNext;
}
return cur;
}
public ListNode middleNode() {
if (head == null) {
return null;
}
ListNode cur = head;
int count = 0;
while (cur != null) {
cur = cur.next;
count++;
}
count /= 2;
cur = head;
while (count > 0) {
cur = cur.next;
count--;
}
return cur;
}
public ListNode findKthToTail(int k){
if(k <= 0 || head == null){
return null;
}
ListNode fast = head;
ListNode slow = head;
while(k - 1 != 0){
fast = fast.next;
if(fast == null){
return null;
}
k--;
}
while(fast.next != null) {
fast = fast.next;
slow = slow.next;
}
return slow;
}
这个是自己构造的单链表,里面由个内部类(在一个class中定义内部类,在另外一个类中要调用必须要点 内部类的外class的名字调用)。next 要存下一个的地址,因为(int[] a = new int[])这个a其实存放的是地址,所以在内部类中也这样子存放地址。
2.2自己改造的双链表LinkedList
public class LinkedList {
static class ListNode{
public int val;
public ListNode prev;
public ListNode next;
public ListNode(int val){
this.val = val;
}
}
public ListNode head;
public ListNode last;
public void addFirst(int data) {
ListNode node = new ListNode(data);
if(head == null){
head = node;
last = node;
return;
}
node.next = head;
head.prev = node;
head = node;
}
public void addLast(int data) {
ListNode node = new ListNode(data);
if(head == null) {
head = node;
last = node;
return;
}
last.next = node;
node.prev = last;
last = node;
}
private void checkPos(int pos) {
if(pos < 0 || pos > size()){
throw new CheckPosException("下标异常"+pos);
}
}
private ListNode searchIndex(int pos){
ListNode cur = head;
while(pos > 0) {
cur = cur.next;
pos--;
}
return cur;
}
public void addIndex(int index, int data) {
checkPos(index);
if(index == 0){
addFirst(data);
return;
}
if(index == size()){
addLast(data);
return;
}
ListNode node = new ListNode(data);
ListNode cur = searchIndex(index);
node.next = cur;
cur.prev.next = node;
node.prev = cur.prev;
cur.prev = node;
}
public boolean contains(int key) {
ListNode cur = head;
while(cur != null){
if(cur.val == key){
return true;
}
cur = cur.next;
}
return false;
}
public void remove(int key) {
isEmpty();
ListNode cur = head;
while(cur != null){
if(cur.val == key){
if(cur == head){
head = head.next;
if(head != null){
head.prev =null;
}
} else {
cur.prev.next = cur.next;
if(cur.next != null){
cur.next.prev = cur.prev;
} else{
last = last.prev;
}
}
return;
} else {
cur = cur.next;
}
}
}
public void removeAllKey(int key) {
isEmpty();
ListNode cur = head;
while(cur != null){
if(cur.val == key){
if(cur == head){
head = head.next;
if(head != null){
head.prev =null;
}
} else {
if(cur.next != null){
cur.next.prev = cur.prev;
} else{
last = last.prev;
}
}
} else {
cur = cur.next;
}
}
}
public int size() {
if(head == null) {
return 0;
}
int count = 0;
ListNode cur = head;
while(cur != null) {
cur = cur.next;
count++;
}
return count;
}
private void isEmpty(){
if(head == null){
throw new IsEmptyException("该链表为空,无法进行该操作");
}
}
public void display() {
isEmpty();
ListNode cur = head;
while(cur != null){
System.out.print(cur.val + " ");
cur = cur.next;
}
System.out.println();
}
public void clear() {
head =null;
last = null;
}
}
与单链表相比内部类多了一个prev 是存放前一个的地址,也多了last 还标记最后一个元素的位置来方便插入和删除,但是双链表对于单链表可用性更高。
2.3 ArrayList 和 链表的区别
3. 简单来捞捞栈和队列
3.1 栈
栈的定义:
一种特殊的线性表,其 只允许在固定的一端进行插入和删除元素操作 。进行数据插入和删除操作的一端称为栈 顶,另一端称为栈底。栈中的数据元素遵守后进先出LIFO ( Last In First Out )的原则。压栈:栈的插入操作叫做进栈 / 压栈 / 入栈, 入数据在栈顶 。出栈:栈的删除操作叫做出栈。 出数据在栈顶 。
栈的使用方法:
3.2 队列
队列的定义:
队列 :只允许在一端进行插入数据操作,在另一端进行删除数据操作的特殊线性表,队列具有先进先出 FIFO(First In First Out) 入队列:进行插入操作的一端称为 队尾( Tail/Rear ) 出队列:进行删除操作的一端称为 队头。
队列的使用方法: