目录
线性表
顺序表
11 | 32 | 65 | 14 | 32 | 22 | 14 | 8 | 12 |
0 1 2 3 4 5 6 7 8
像这种数组形式方便理解
顺序表的代码实现:
代码实现
public class SequenceList<T> {
//存储元素的数组
private T[] a;
//记录顺序表中的元素个数
private int N;
//构造方法
public SequenceList(int capacity)
{ //初始化数组
this.a=(T[])new Object[capacity];
this.N=0;
}
//将一个线性表置为空表
public void reset() {
this.N=0;
}
//判断当前线性表是否为空表
public boolean isEmpty()
{
return N==0;
}
//获取线性表的长度
public int length()
{
return N;
}
//获取指定位置的元素
public T get(int i)
{
return a[i];
}
//向线性表中添加元素
public void insert(T t)
{
a[N++]=t;
}
//在i元素处插入元素t
public void insert(int i,T t)
{
//先把i索引处的元素及其后面索引处的元素依次向后移动一位
for(int index=N-1;index>i;index--)
{
a[index]=a[index-1];
}
//再把t元素放到i元素处即可
a[i]=t;
}
//删除指定位置i处的元素,并返回该元素
public T remove(int i)
{
//记录索引i处的值
T current=a[i];
//索引i后面的元素依次向前移动一位即可
for(int index= i;index<N-1;index++)
{
a[index]=a[index+1];
}
N--;
return current ;
}
//查找t元素第一次出现的位置
public int indexOf(T t)
{
for(int i=0;i<N;i++)
{
if(a[i]==t)
{
return i;
}
}
return -1;
}
public static void main(String[] args)
{
//创建顺序表对象
SequenceList<String>s =new SequenceList<>(10);
//测试插入
s.insert("姚明");
s.insert("小明");
s.insert("小王");
s.insert(1,"科比");
//测试获取
String gets=s.get(1);
System.out.println("索引1处的结果为:"+gets);
//测试删除
String removeresult =s.remove(0);
System.out.println("删除的元素是:"+removeresult);
//测试清空
s.reset();
System.out.println("清空后的元素个数为:"+s.length());
}
}
时间复杂度
链表
我们可以设计一个类,用来描述结点这个事物,用一个属性描述这个结点存储的元素,用来另外一个属性描述这个结点的下一个结点。
类名 | Node<T> |
构造方法 | Node(T t,Node next):创建Node对象 |
成员变量 | T item:存储数据 Node next:指向下一个结点 |
public class Node<T> {
//存储元素
public T item;
//指向下一个结点
public Node next;
public Node(T item,Node next)
{
this.item=item;
this.next=next;
}
public static void main(String[] args)
{
//构建结点
Node<Integer>first=new Node<Integer>(10,null);
Node<Integer>second=new Node<Integer>(20,null);
Node<Integer>third=new Node<Integer>(30,null);
//生成链表
first.next=second;
second.next=third;
}
}
单向链表
单向链表代码实现
import java.util.Iterator; //Iterable接口用来表面可以进行迭代
public class LinkList<T> implements Iterable<T> {
//记录头结点
private Node head;
//记录链表的长度
private int N;
//结点类
private class Node{
//存储数据
T item;
//下一个结点
Node next;
public Node(T item,Node next)
{
this.item=item;
this.next=next;
}
}
public LinkList() {
//创建结节点
this.head=new Node(null,null);
//初始化元素个数
this.N=0;
}
//清空链表
public void clear()
{
head.next=null;//使头结点不指向下一个结点
this.N=0;
}
//获取链表的长度
public int length()
{
return N;
}
//判断链表是否为空
public boolean isEmpty()
{
return N==0;
}
//获取指定位置i处的元素
public T get(int i)
{
//通过循环,从头结点开始往后找,依次找i次,就可以找到对应的元素
Node n=head.next;//不断的把n向后变化,直到变化到第i个位置处
for(int index=0;index<i;index++)
{
n=n.next;
}
return n.item;
}
//向链表中添加元素t
public void insert(T t)
{
//找到当前最后一个结点
Node n=head;
while(n.next!=null)
{
n=n.next;
}
//创建新结点,保存元素t
Node newNode =new Node(t,null);
//让当前最后一个结点指向新结点
n.next=newNode;
//元素的个数加1
N++;
}
//向指定位置i处,添加元素t
public void insert(int i,T t)
{
//找到i位置前一个节点
Node p=head;
for(int index=0;index<=i-1;index++)
{
p=p.next;
}
//找到i位置的节点
Node c=p.next;
//创建新结点,并且新结点需要指向原来i位置的结点
Node newNode =new Node(t,c);
//原来i位置的前一个结点指向新结点即可
p.next=newNode;
//元素的个数+1
N++;
}
//删除指定位置i处的元素,并返回被删除的元素
public T remove(int i)
{
//找到i位置的前一个结点
Node p=head;
for(int index=0;index<=i-1;i++)
{
p=p.next;
}
//要找到i位置的结点
Node c=p.next;
//找到i位置的下一个结点
Node nextNode=c.next;
//前一个节点指向下一个结点
p.next=nextNode;
//元素个数减1
N--;
return c.item;
}
//查找元素t在链表中第一次出现的位置
public int indexOf(T t)
{
//从头结点开始,依次找到每一个结点,取出item,和t比较,如果相同,就找到了
Node n=head;
for(int index=0;n.next!=null;index++)
{
n=n.next;
if(n.item==t)
return index;
}
return -1;
}
public Iterator<T> iterator()
{
return new LIterator();
}
private class LIterator implements Iterator{
private Node n;
public LIterator()
{
this.n=head;
}
@Override
public boolean hasNext() {
return n.next!=null;
}
@Override
public Object next()
{
n=n.next;
return n.item;
}
}
}
import java.util.Arrays;
public class test{
public static void main(String[] args)
{
//创建单向链表对象
LinkList <String> s1= new LinkList<>();
//测试插入
s1.insert("姚明");
s1.insert("科比");
s1.insert("小王");
s1.insert(1,"成龙");
for(String s:s1)
{
System.out.println(s);
}
System.out.println("————————————————————————————————————————————————————");
//测试获取
String getresult =s1.get(1);
System.out.println("获取索引1处的结果为:"+getresult);
//测试删除
String removeresult =s1.remove(0);
System.out.println("删除元素是:"+removeresult);
//测试清空
s1.clear();
System.out.println("清空后的线性表中的元素个数为:"+s1.length());
}
}
双向链表
代码实现
import java.util.Iterator;
//Iterable接口用来表面可以进行迭代
public class TowWayLinkList<T> implements Iterable<T> {
//首结点
private Node head;
//尾结点
private Node last;
//链表的长度
private int N;
//结点类
private class Node{
//存储数据
public T item;
//指向上一个结点
public Node pre;
//指向下一个结点
public Node next;
public Node(T item,Node pre,Node next)
{
this.item=item;
this.next=next;
this.pre=pre;
}
}
public TowWayLinkList()
{
//初始化头结点和尾结点
this.head=new Node(null,null,null);
this.last=null;//刚开始尾结点没有数据
//初始化元素个数
this.N=0;
}
//清空链表
public void clear()
{
this.head.next=null;
this.head.item=null;
this.head.pre=null;
this.last=null;
this.N=0;
}
//获取链表长度
public int length()
{
return N;
}
//判断链表是否为空
public boolean isEmpty()
{
return N==0;
}
//获取第一个元素
public T getFirst()
{ if(isEmpty())
{
return null;
}
return head.next.item;
}
//获取最后一个元素
public T getLast()
{
if(isEmpty())
{
return null;
}
return last.item;
}
//插入元素t
public void insert(T t)
{
//如果链表为空,1.创建新的结点,2.并让新结点成为尾结点,3.并让头结点指向新结点
if(isEmpty())
{
//1.创建新结点
Node newNode=new Node(t,head,null);
//2.让新结点成为尾结点
last=newNode;
//3.让头结点指向新结点
head.next=last;
}
else//如果链表不为空
{
//创建新的结点
Node oldlast=last;
Node newNode=new Node(t,oldlast,null);
//让当前的尾结点指向新结点
oldlast.next=newNode;
//让新结点称为尾结点
last=newNode;
}
N++;//元素个数加1
}
//向指定位置i处插入元素t
public void insert(int i,T t)
{
//找到i位置的前一个结点
Node pre=head;
for(int index=0;index<=i-1;index++)
{
pre=pre.next;
}
//找到i位置的结点
Node c=pre.next;
//创建新结点
Node newNode=new Node(t,pre,c);
//让i位置的前一个结点的下一个结点变为新结点
pre.next=newNode;
//让i位置的前一个结点变为新结点
c.pre=newNode;
//元素个数+1
N++;
}
public T get(int i)
{
Node n=head.next;
for(int index=0;index<i;index++)
{
n=n.next;
}
return n.item;
}
//找到元素t在链表中第一次出现的位置
public int indexOf(T t)
{
//从头结点开始,依次找到每一个结点,取出item,和t比较,如果相同,就找到了
Node n=head;
for(int index=0;n.next!=null;index++)
{
n=n.next;
if(n.item==t)
return index;
}
return -1;
}
//删除指定位置i处的元素,并返回被删除的元素
public T remove(int i)
{
//找到i位置的前一个结点
Node pre=head;
for(int index=0;index<=i-1;i++)
{
pre=pre.next;
}
//要找到i位置的结点
Node c=pre.next;
//找到i位置的下一个结点
Node nextNode=c.next;
//让i位置的前一个结点的下一个结点变为i位置的下一个结点
pre.next=nextNode;
//让i位置的后一个节点的上一个结点变为i位置的上一个结点
nextNode.pre=pre;
//元素个数减1
N--;
return c.item;
}
@Override
public Iterator<T> iterator() {
// TODO Auto-generated method stub
return new TIterator();
}
private class TIterator implements Iterator{
private Node n;
public TIterator()
{
this.n=head;
}
@Override
public boolean hasNext() {
return n.next!=null;
}
@Override
public Object next()
{
n=n.next;
return n.item;
}
}
}
import java.util.Arrays;
public class test{
public static void main(String[] args)
{
//创建双向链表对象
TowWayLinkList <String> s1= new TowWayLinkList<>();
//测试插入
s1.insert("姚明");
s1.insert("科比");
s1.insert("小王");
s1.insert(1,"成龙");
for(String s:s1)
{
System.out.println(s);
}
System.out.println("——————————————————————————————————————————————————");
System.out.println("第一个元素是"+s1.getFirst());
System.out.println("第后一个元素是"+s1.getLast());
System.out.println("————————————————————————————————————————————————————");
//测试获取
String getresult =s1.get(1);
System.out.println("获取索引1处的结果为:"+getresult);
//测试删除
String removeresult =s1.remove(0);
System.out.println("删除元素是:"+removeresult);
//测试清空
s1.clear();
System.out.println("清空后的线性表中的元素个数为:"+s1.length());
}
}
时间复杂度分析
视频笔记: