MyArrayList 以及 MyLinkedList
数据结构是我们在编程学习中重要的点之一:
在此翻看书籍,总结一下知识点,书写一下自己的代码,凡是在注释里的有自己的疏忽的点,希望自己引以为戒。
代码如下:
1 package MyArrayList; 2 3 import java.util.Arrays; 4 5 /** 6 * @Version 1.0 7 * @Author: Hu 8 * @DATE: 2020/11/30 9:47 9 * Content:顺序表 10 */ 11 public class MyArrayList { 12 //成员属性 13 public int[] elem; 14 public int usedSize; 15 16 //构造方法 17 public MyArrayList(){ 18 this.elem = new int[10]; 19 this.usedSize = 0; 20 } 21 public MyArrayList(int capacity){ 22 this.elem = new int[capacity]; 23 this.usedSize = 0; 24 } 25 public void display(){ 26 // for(int x: ){ 27 // 28 // } 29 for(int i = 0 ; i < this.usedSize ; i++){ 30 System.out.print(this.elem[i]+" "); 31 } 32 System.out.println(); 33 } 34 public void add(int pos,int data){ 35 //1、pos位置是否合法问题 pos<0 或者 pos超过数组长度 36 //2、数组是否满 37 //3、移动数组需要从后往前 38 if(pos < 0 || pos >usedSize){//这里需要习惯使用this.usedSize 39 //记得加上return 40 System.out.println("error"); 41 return ;//表示函数结束 42 } 43 if(usedSize == elem.length){//这里需要习惯使用this 44 //记得加上return 45 System.out.println("error"); 46 return; 47 } 48 if(isFull()){ 49 resize(); 50 } 51 // for(int i = 0; i < usedSize ;i++){ 52 // while(pos != usedSize-i){ 53 // elem[usedSize-1] = elem[usedSize-1-i]; 54 // } 55 // if(pos == usedSize-1-i){ 56 // elem[pos] = data; 57 // } 58 // } 59 // this.usedSize++; 60 for (int i = this.usedSize-1; i >= pos ; i--) { 61 this.elem[i+1] = this.elem[i]; 62 } 63 this.elem[pos] = data; 64 this.usedSize++; 65 } 66 public boolean contains(int toFind){ 67 if(usedSize == 0){ 68 return false; 69 } 70 for (int i = 0; i < usedSize; i++) { 71 if(elem[i] == toFind){ 72 return true; 73 } 74 } 75 return false; 76 } 77 public int search(int toFind){ 78 if(usedSize == 0){ 79 return -1; 80 } 81 for (int i = 0; i < usedSize; i++) { 82 if(this.elem[i] == toFind){ 83 return i; 84 } 85 } 86 return -1; 87 } 88 public int getPos(int pos){//获取pos位置的元素 89 if(pos >= usedSize || pos < 0){ 90 return -1; 91 } 92 // for (int i = 0; i < usedSize; i++) { 93 // if(i == pos){ 94 // return i; 95 // } 96 // } 97 return this.elem[pos]; 98 } 99 public void setPos(int pos,int value){ 100 if(pos < 0 || pos > this.usedSize){ 101 System.out.println("位置不合法"); 102 return; 103 } 104 this.elem[pos] = value; 105 } 106 public void remove(int toRemove){ 107 int index = search(toRemove); 108 if(index == -1){ 109 System.out.println("没有这个数字"); 110 return ; 111 } 112 //int j = index; 113 for (int i = index; i < this.usedSize-1; i++) { 114 this.elem[i] = this.elem[i+1]; 115 } 116 this.usedSize--; 117 } 118 public void removeAll (int toRemove) { 119 int index = this.usedSize; 120 for (int i = 0; i < index; i++) { 121 remove(toRemove); 122 } 123 } 124 public int size(){ 125 // int count = 0; 126 // for (int tmp : elem) { 127 // count++; 128 // } 129 // return count; 130 return this.usedSize; 131 } 132 public void clear(){ 133 this.usedSize = 0; 134 System.out.println("已经清空"); 135 } 136 public int[] resize(){ 137 //进行拷贝 138 // int[] newElem = new int[elem.length*2]; 139 // for (int i = 0; i < elem.length; i++) { 140 // newElem[i] = elem[i]; 141 // } 142 // return newElem; 143 return this.elem = 144 Arrays.copyOf(this.elem,this.elem.length*2); 145 } 146 public boolean isFull(){ 147 if(this.elem.length == this.usedSize){//记得加上this 148 return true; 149 } 150 return false; 151 } 152 }
上述为ArrayList,
下方为ArrayLinkedList:
1 package MyLinkedList; 2 3 /** 4 * @Version 1.0 5 * @Author: Hu 6 * @DATE: 2020/11/30 14:47 7 * Content:对象的属性用过.号来访问 8 */ 9 public class MySingleList { 10 public Node head;//定位头结点的引用 唯一作用 11 public boolean isEmpty(){//判断是否为空 12 if(head == null){ 13 return true; 14 } 15 return false; 16 } 17 //头插法 18 public void addFirst(int data){ 19 // if(head == null){ 20 // Node node = new Node(10); 21 // head = node; 22 // } 23 // head.next.data = data; 24 /** 25 * 通过data创建Node对象(错误方式:1、head = node; 2、node.next = head;) 26 * 正确方式: 27 * 1、node.next = head; 28 * 2、head = node; 29 */ 30 //1、通过data构造一个Node对象 31 // System.out.println(isEmpty()); 32 Node node = new Node(data);//小写的node就是对象的引用 33 if(isEmpty()){ 34 this.head = node;//head = node;忘记写this 35 //head 保存了 node 的值 36 /** 37 * 头结点所有: 38 * this.head = node; 39 * head 保存了node 的值 40 * head 引用了node引用的对象 41 */ 42 /** 43 * 链表的插入来说 一定要先绑住后面 44 * node.next = head; 45 * head = node; 46 */ 47 return; 48 } 49 /* 50 * 引用-》值-》地址 51 * */ 52 //2、使用头插的方式,将这个节点放置在头处 53 node.next = this.head; 54 this.head = node; 55 56 } 57 //尾插法 58 public void addLast(int data){ 59 Node node = new Node(data); 60 if(this.head == null){ 61 head.next = node; 62 return;//如果为空,插入之后就返回 63 } 64 Node cur = this.head; 65 while(cur.next != null){ 66 cur = cur.next; 67 } 68 cur.next = node; 69 } 70 public Node searchPrev(int index){//寻找第index-1的位置 71 Node cur = this.head; 72 int count = index-1; 73 while(count == 0){ 74 cur = cur.next; 75 count--; 76 } 77 return cur; 78 } 79 //任意位置插入,第一个数据节点为0号下标 80 public void addIndex(int index,int data){ 81 int length = size(); 82 if(index <0 || index > length){ 83 return; 84 } 85 Node node = new Node(data); 86 if(index == 0){ 87 addFirst(data); 88 return; 89 } 90 Node cur = searchPrev(index); 91 node.next = cur.next; 92 cur.next = node; 93 } 94 //查找是否包含关键字key是否在单链表当中 95 public boolean contains(int key){ 96 Node cur = this.head;//cur指向了 head 所指向的引用 97 //Node node = new Node(key); 而这个是通过new的方式创建了一个新的对象,然后交由node来引用 98 while(cur != null){ 99 if(cur.data == key){ 100 return true; 101 } 102 cur = cur.next; 103 } 104 return false; 105 } 106 //删除第一次出现关键字为key的节点 107 public void remove(int key){ 108 // if(contains(key)){//判断是否包含这个key值 109 // 110 // Node node = searchPrev(key);//包含则找到这个节点的唯一前驱 111 // node.next = node.next.next;//指向 112 // } 113 if(this.head.data == key){ 114 this.head = this.head.next; 115 return; 116 } 117 Node node = searchPrevNode(key); 118 if(node == null){ 119 System.out.println("没有这个前驱"); 120 return; 121 } 122 node.next = node.next.next; 123 //Node del = searchPrevNode(key); 124 //node.next = del.next; 125 } 126 public Node searchPrevNode (int key) { 127 Node cur = this.head; 128 while(cur.next != null){ 129 if(cur.next.data == key){ 130 return cur; 131 } 132 cur = cur.next; 133 } 134 return null; 135 } 136 //删除所有值为key的节点 137 public void removeAllKey(int key){ 138 Node cur = this.head; 139 int count = 0; 140 while(cur != null){ 141 searchPrevNode(key); 142 cur = cur.next; 143 count++; 144 } 145 for (int i = 0; i < count; i++) { 146 remove(key); 147 } 148 } 149 //得到单链表的长度 150 public int size(){ 151 Node tmp = this.head; 152 int count = 0; 153 while(tmp != null){ 154 tmp = tmp.next; 155 count++; 156 } 157 return count; 158 } 159 public void display(){//打印 链表里边的数值 160 //为了方便遍历,所以使用Node 定义一个引用 cur 161 //Node cur = this.head; 162 //cur = cur.next; 163 Node cur = this.head; 164 while(cur != null){ 165 System.out.print(cur.data+" "); 166 cur = cur.next; 167 } 168 System.out.println(); 169 } 170 public void clear(){ 171 this.head = null; 172 } 173 }
在创建MySingleList之前,需要先创建节点类:
1 package MyLinkedList; 2 3 /** 4 * @Version 1.0 5 * @Author: Hu 6 * @DATE: 2020/11/30 14:48 7 * Content: 8 */ 9 public class Node {//class Node之后 Node类型已经存在了,所以可以使用Node定义一个变量 10 public int data; 11 public Node next; 12 13 public Node(int data){ 14 //没有对next进行初始化,这是因为不知道next下一个会指向哪里 15 this.data = data; 16 } 17 }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 三行代码完成国际化适配,妙~啊~
· .NET Core 中如何实现缓存的预热?