java
一、数据结构基础
1.数组属于顺序存储中,由于每个元素的存储位置都可以通过简单计算得到,所以访问元素的时间都相同(直接访问数组下标);
2.链表属于数据的链接存储,由于每个元 素的存储位置是保存在它的前驱或后继结点中的,所以只有当访问到其前驱结点或后继结点后才能够按指针访问到自己,访问任一元素的时间与该元素结点在链接存储中的位置有关。
3.区别:链表和数组的差异决定了它们的不同使用场景,如果需要很多对数据的访问,则适合使用数组;如果需要对数据进行很多移位操作,则设和使用链表。
二、封装数组功能实现
功能:
1.向数组添加元素-改进方法(考虑时间复杂度和空间复杂度)
2.取指定位置的数据
3.向队列的指定位置添加一个字符
import java.lang.reflect.Array;
import java.util.Arrays;
//可变数组需要考虑时间复杂度和空间复杂度
//如何向数组中插入一个值的改进做法
public class myqueue {
public String[] sa;
private int count=0;
private int count2=0;
//将类构造器初始化,便于输入长度参数
public myqueue(int initlen) {
sa=new String[initlen];
}
//1.向队列sa中增加一个元素,由于数组是固定长度,所以需要自定方法,这种方法
public void add(String s) {
//构造器初始化
//如果新增加的在initlen长度之内,不需要初始化直接放入
sa[count]=s;
count++;
//一旦增加的字符长度大于初始化数组的长度
//定义长度为初始的两倍,并且把新的数组的指针赋予sa数组
if (count>=sa.length) {
String[] temp=new String[2*sa.length];
//把sa的数据传过来
for(int j=0;j<sa.length;j++) {
temp[j]=sa[j];
}
//把指针换一下 那么此时temp就是增加长度的原数组sa
sa=temp;
}
System.out.println(Arrays.toString(sa));
}
//取指定位置的数据
public String get(int index) {
String s=sa[index];
return s;
}
//获取队列的长度
public int size() {
return sa.length;
}
//获取存储数据的长度
public int len() {
return count;
}
//向队列的指定位置添加一个字符
public void insert(int index,String s) {
//创建一个新的数组,index之前的复制,index处相等,index后的复制
String[] newsa=new String[sa.length+1];
for (int i=0;i<index;i++) {
newsa[i]=sa[i];
}
newsa[index]=s;
for(int i=index+1;i<sa.length+1;i++){
newsa[i]=sa[i-1];
}
sa=newsa;
System.out.println(Arrays.toString(sa));
}
public static void main(String[] args) {
myqueue mq=new myqueue(1);
mq.add("1");
mq.add("2");
mq.add("3");
mq.add("4");
mq.add("5");
mq.insert(3, "100");
mq.insert(4, "300");
System.out.println(mq.size()+"有效数字是"+mq.len());
}
}
三、封装链表功能实现
1.创建链表的两种方法
2.往里加元素**(双参数方法–重点)**
3.获取长度打印等
//链表基本概念 是一种常见的基础数据结构,是一种线性表,但是并不会按线
//性的顺序存储数据,而是在每一个节点里存到下一个节点的地址。
//以下情况使用 LinkedList :
//1.你需要通过循环迭代来访问列表中的某些元素。
//2.需要频繁的在列表开头、中间、末尾等位置进行添加和删除元素操作。
//创建一个节点
class node{
String v;//这个节点的内部值
node next; //这个node类存储了下一个节点的node
//构造器 返回我的node类,便于多次调用
node(){
}
}
public class nodetest {
private static node root;
private node last;
private static int count;
//创建链表
public node createlink() {
//调用我的node类 第一个也叫根节点
root =new node();
root.v="1";
//继续创建节点 给内部值赋值
node n2 =new node();
n2.v="2";
node n3 =new node();
n3.v="3";
//给下个节点传递编号
root.next=n2;
n2.next=n3;
last=n3;
count=3;
return root;
}
//往里加元素
public void addlink(String s) {
//第一次直接创建
if(root==null) {
root=new node();
root.v=s;
last=root;
//为了便于循环,把root指针赋给另外一个
}else {
//以后的在后面加即可
node nd=new node();
last.next=nd;
nd.v=s;
last=nd;
}
count++;
}
//创建方法打印列表
public void printnode(node root) {
node tem=root;
while(tem!=null) {
String s=tem.v;
System.out.println("节点值为"+s);
tem=tem.next;
}
}
//链表的长度
public int size() {
return count;
}
public static void main(String[] args) {
// nodetest nt=new nodetest();
nodetest nt=new nodetest();
node root= nt.createlink();
nt.addlink("4");
nt.addlink("5");
nt.printnode(root);
System.out.println("链表总长度为"+count);
}
}
四、链表转化为数组
较为简单,依次转化即可
import java.util.Arrays;
//主要介绍链表转化成数组
//链表类
class ListNode{
//链表值
int val;
//链表的下一个节点
ListNode next;
//构造器,便于传入参数
ListNode(int x){
//内部的值等于传入的这个参数
val=x;
}
}
public class Test1 {
//将链表转化成数组
public int[] listNodeToArray(ListNode lst) {
//调用size函数确定链表的长度
int size=listNodeSize(lst);
//生成一个同样长度的数组
int[] ints=new int[size];
int index=0;//计数器循环进去
while(lst!=null) {
ints[index]=lst.val;
//index增长 并且链表确定下一个
index++;
lst=lst.next;
}
return ints;
}
//求链表的长度
public int listNodeSize(ListNode lst) {
int size=0;
while(lst !=null) {
size++;
lst=lst.next;
}
return size;
}
//打印一个链表
public void print(ListNode lst) {
while(lst!=null) {
System.out.println("链表的值"+lst.val);
lst=lst.next;
}
}
//打印输出你转置出来的数组
public void printArrays(int[] ints) {
//打印数组的固定操作
System.out.println(Arrays.toString(ints));
}
public static void main(String[] args) {
Test1 test1=new Test1();
ListNode lst1=new ListNode(0);
ListNode lst2=new ListNode(1);
ListNode lst3=new ListNode(2);
ListNode lst4=new ListNode(3);
lst1.next=lst2;
lst2.next=lst3;
lst3.next=lst4;
test1.print(lst1);
int[] kkkk=test1.listNodeToArray(lst1);
test1.printArrays(kkkk);
}
}
五、数组转化为链表
因为根节点用root 表示,为了便于循环,双指针
//主要介绍数组转化成链表
public class Test2 {
//把数组转化成链表
public ListNode arrayToListNode(int[] s) {
//生成根部节点
ListNode root=new ListNode(s[0]);
//因为循环不好调用根节点,在生成一个
ListNode other=new ListNode(s[0]);
other=root;
//生成另外的节点
for(int i=1;i<s.length;i++) {
ListNode temp=new ListNode(s[i]);
other.next=temp; //指定temp是other的下一个节点
other=temp; //将此时的temp作为下一次的other
}
return root;
}
//打印链表
public void print(ListNode lst) {
while(lst!=null) {
System.out.println(lst.val+"");
lst=lst.next;
}
}
public static void main(String[] args) {
Test2 test2=new Test2();
int[] a= {1, 9, 9, 9, 9, 9, 9, 9, 9, 9};
ListNode lst=test2.arrayToListNode(a);
test2.print(lst);
}
}