世界只有一种英雄主义,就是认清生活真相之后依然热爱生活
目录
1.数据结构
2.线性表
3.顺序表
创建类以及成员属性和成员方法
创建对象
1.打印顺序表: public void display()
2.返回顺序表数据个数:public int size()
3.在pos位置添加data数据:public void add(int pos,int data)
4.判定是否包含某个元素:public boolean contains(int toFind)
5.查找某个元素对应的位置:public int search(int toFind)
6.获取 pos 位置的元素:public int getPos(int pos)
7.给 pos 位置的元素设为 value:public void setPos(int pos, int value)
8.删除第一次出现的关键字key:public void remove(int toRemove)
9.清空顺序表:public void clear()
4.源码
数据结构是计算机存储、组织数据的方式。数据结构是指相互之间存在一种或多种特定关系的数据元素的集合。通常情况下,精心选择的数据结构可以带来更高的运行或者存储效率。
线性表(linear list)是n个具有相同特性的数据元素的有限序列。
线性表是一种在实际中广泛使用的数据结构,常见 的线性表:顺序表、链表、栈、队列、字符串... 线性表在逻辑上是线性结构,也就说是连续的一条直线。
但是在物理结构上并不一定是连续的,线性表在物理上存储 时,通常以数组和链式结构的形式存储。
数组
0 | 1 | 2 | 3 | 4 | 5 |
线性表(链表)
3.1 概念及结构
顺序表是用一段物理地址连续的存储单元依次存储数据元素的线性结构,一般情况下采用数组存储。在数组上完成数据的增删查改。
顺序表一般可以分为:
静态顺序表适用于确定知道需要存多少数据的场景. 静态顺序表的定长数组导致N定大了,空间开多了浪费,开少了不够用
相比之下动态顺序表更灵活, 根据需要动态的分配空间大小。
顺序表的底层就是一个数组,不过我们知道数组的大小及内容。
public class MyArrayList {
public int[] elem;
public int usedSize;
public MyArrayList(){
this.elem = new int[10];
}
}
数组名elem,usedSize表示有效的数据个数,数组初始化this.elem = new int[10];
public class MAIN {
public static void main(String[] args) {
MyArrayList myArrayList = new MyArrayList();
}
}
利用for循环打印即可
public void display(){
for (int i = 0; i < this.usedSize; i++) {
System.out.println(this.elem[i]+" ");
}
System.out.println();
}
直接return usedSize
public int size(){
return this.usedSize;
}
首先,判断pos位置的合法性:
其次,判断顺序表是否放满:
public boolean isFull(){
return this.usedSize == this.elem.length;
}
若顺序表已经放满,需要对顺序表进行扩容,实际上就是对数组进行扩容,可用Arrays.copyOf()进行扩容 :this.elem = Arrays.copyOf(this.elem,2*this.elem.length);
注意Arrays.copyOf()返回的是新数组,这里我们需要用原来的数组进行接收。
public void add(int pos,int data){
if(pos < 0||pos > usedSize){
return;
}
if(isFull()){
this.elem = Arrays.copyOf(this.elem,2*this.elem.length);
}
}
public boolean isFull(){
return this.usedSize == this.elem.length;
}
最后,进行数据的添加:
在pos位置进行添加数据,需要把顺序表中pos位置后面的数据(包括pos位置)向后挪一位,然后在pos位置添加数据,最后usedSize++。
for (int i = this.usedSize; i >= pos ; i--) {
this.elem[i+1] = this.elem[i];
}
this.elem[pos] = data;
this.usedSize++:
这样就完成了public void add(int pos,int data)
public void add(int pos,int data){
if(pos < 0||pos > usedSize){
return;
}
if(isFull()){
this.elem = Arrays.copyOf(this.elem,2*this.elem.length);
}
for (int i = this.usedSize; i >= pos ; i--) {
this.elem[i+1] = this.elem[i];
}
this.elem[pos] = data;
this.usedSize++:
}
public boolean isFull(){
return this.usedSize == this.elem.length;
}
这时,我们简单测试以下前面写的数据添加以及顺序表的打印
public class MAIN {
public static void main(String[] args) {
MyArrayList myArrayList = new MyArrayList();
myArrayList.add(0,11);
myArrayList.add(1,22);
myArrayList.add(2,33);
myArrayList.add(3,44);
myArrayList.add(4,55);
myArrayList.display();
}
}
运行结果:
利用for循环即可完成
public boolean contains(int toFind){
for (int i = 0; i < this.usedSize; i++) {
if(this.elem[i] == toFind){
return true;
}
}
return false;
}
找到返回下标,找不到返回-1(因为数组下标没有负数),利用for循环即可完成, 逻辑与public boolean contains(int toFind)相似
public int search(int toFind){
for (int i = 0; i < this.usedSize; i++) {
if(this.elem[i] == toFind){
return i;
}
}
return -1;
}
1.判断pos位置的合法性:
2.判断顺序表是否为空:
public boolean isEmpty(){
return this.usedSize == 0;
}
3.返回pos位置元素
public int getPos(int pos){
if(pos < 0||pos >= this.usedSize){
return -1;
}
if(isEmpty()){
return -1;
}
return this.elem[pos];
}
public boolean isEmpty(){
return this.usedSize == 0;
}
注意:前两个if语句返回-1是没有办法的(因为public int getPos(int pos)返回值类型为int,但顺序表中的元素也有可能为-1,这里现在写为return -1,后期学到更多知识,这里可以抛异常)
1.判断pos位置的合法性:
2.判断顺序表是否为空:
利用isEmpty();
3.将pos位置元素更改为value:
public void setPos(int pos, int value){
if(pos < 0 || pos >=this.usedSize){
return;
}
if(isEmpty()){
return;
}
this.elem[pos] = value;
}
1.判断顺序表是否为空:
利用isEmpty();
2.查找需要删除的数据toRemove,并返回其下标:
这里,我们利用之前已经写过的第5个方法search(int toFind)来完成
3.删除toRemove后,将后面的数据依次前移一位this.elem[i] = this.elem[i+1]
4.usedSize--
public void remove(int toRemove){
if(isEmpty()){
return;
}
int index = search(toRemove)
if(-1 == index){
return;
}
for (int i = index; i < this.usedSize - 1; i++) {
this.elem[i] = this.elem[i+1];
}
this.usedSize--;
}
注意:for循环的边界是this.usedSize - 1,是因为若i = this.usedSize,则i+1会越界,导致程序报错
1.对于仅含有普通类型(非引用类型)的顺序表,将usedSize的值置为0 即可
public void clear(){
this.usedSize = 0;
return;
}
2.对于引用类型顺序表,需要将顺序表中的每一个元素置为null,且usedSize置为0
public void clear(){
for (int i = 0; i < usedSize; i++) {
this.elem[i] = null;
}
this.usedSize = 0;
return;
}
import java.util.Arrays;
public class MyArrayList {
public int[] elem;
public int usedSize;
public MyArrayList(){
this.elem = new int[10];
}
//打印顺序表
public void display(){
for (int i = 0; i < this.usedSize; i++) {
System.out.println(this.elem[i]+" ");
}
System.out.println();
}
//获取顺序表长度
public int size(){
return this.usedSize;
}
//在pos位置添加data数据
public void add(int pos,int data){
if(pos < 0||pos > usedSize){
return;
}
if(isFull()){
this.elem = Arrays.copyOf(this.elem,2*this.elem.length);
}
for (int i = this.usedSize; i >= pos ; i--) {
this.elem[i+1] = this.elem[i];
}
this.elem[pos] = data;
this.usedSize++;
}
public boolean isFull(){
return this.usedSize == this.elem.length;
}
//判定是否包含某个元素
public boolean contains(int toFind){
for (int i = 0; i < this.usedSize; i++) {
if(this.elem[i] == toFind){
return true;
}
}
return false;
}
//查找某个元素对应的位置,找不到返回-1
public int search(int toFind){
for (int i = 0; i < this.usedSize; i++) {
if(this.elem[i] == toFind){
return i;
}
}
return -1;
}
//获取 pos 位置的元素
public int gotPos(int pos){
if(pos < 0||pos >= this.usedSize){
return -1;
}
if(isEmpty()){
return -1;
}
return this.elem[pos];
}
public boolean isEmpty(){
return this.usedSize == 0;
}
//给 pos 位置的元素设为 value
public void setPos(int pos, int value){
if(pos < 0 || pos >=this.usedSize){
return;
}
if(isEmpty()){
return;
}
this.elem[pos] = value;
}
//删除第一次出现的关键字key
public void remove(int toRemove){
if(isEmpty()){
return;
}
int index = search(toRemove);
if(-1 == index){
return;
}
for (int i = index; i < this.usedSize - 1; i++) {
this.elem[i] = this.elem[i+1];
}
this.usedSize--;
}
//清空顺序表
public void clear(){
this.usedSize = 0;
return;
}
}