1.列表
在基础数据结构中,列表作为最为基础的一个数据结构进行体现。
2.列表的模型

3.基本算法
1.增加元素(在头部/尾部/其余地方)
2.删除元素(在头部/尾部/其余地方)
3.扩容/缩容
4.获取有效长度
5.判断列表是否为空
6.获取某位置元素(头部/尾部/其余地方)
7.改变某位置的元素
8.寻找元素,返回下标。
9.列表是否包含某元素
10.获取容积
11.清除列表
12.交换列表中两位置的元素
13.重写toString方法
4.实现方法
一,顺序列表

使用数组Date[ ]实现。
-
增加元素
在头部增加,尾部增加,中间增加。
-
删除元素
在头部删除,尾部删除,中间删除。
-
扩容/缩容
-数组中增加元素时,数组已满,则需要扩容。
-数组中删除元素时,一般删除到数组长度的四分之一时,一般将数组的长度删除到原来的一半。则需要缩容。 -
获取有效长度
获取数组的有效长度。
-
判断列表是否为空
获取数组的有效长度是否为0。
-
获取末位置元素
获取数组的有效长度-1的位置的元素。
-
改变某位置的元素
根据数组的下标改变某下标的元素。
-
寻找元素
循环遍历数组判断元素是否相等。返回其下标。
-
列表是否包含某元素
和寻找元素一样,循环遍历数组判断元素是否相等。
-
获取容积
获取数组的总长度。
-
清除列表
-数组的有效长度size是标记数组某位置是否存在元素。
-直接将size置0。 -
交换列表中两位置的元素
在数组中交换两位置之间的元素。
-
重写toString方法
重新拼接字符串。打印输出。
代码:
public class ArrayList<E> implements List<E>{
private E[] data; //容器-存储元素 data.length 最大容量
private int size; //当前列表中元素的个数 有效长度
private static final int DEFAULT_CAPACITY=10;
public ArrayList(){ //默认构造函数中创建一个容量为10的列表
this(DEFAULT_CAPACITY);
}
public ArrayList(int capacity){ //构造函数中创建一个容量为capacity的列表
if(capacity<0){
capacity=DEFAULT_CAPACITY;
}
this.data=(E[]) new Object[capacity];
this.size=0;
}
//O(n)
public void add(int index, E e) { //增加元素
if(index<0||index>size){
throw new IllegalArgumentException("角标非法!");
}
if(size==data.length){
resize(data.length*2);//重置容量
}
for(int i=size;i>index;i--){
data[i]=data[i-1];
}
data[index]=e;
size++;
}
public void addFirst(E e) { //在头部增加
add(0,e);
}
//O(1)
public void addLast(E e) { //在尾部增加
add(size,e);
}
//O(n)
public E remove(int index) { //删除元素
if(index<0||index>=size){
throw new IllegalArgumentException("角标非法!");
}
E res=data[index];
for(int i=index;i<size-1;i++){
data[i]=data[i+1];
}
size--;
if(size==data.length/4&&data.length>DEFAULT_CAPACITY){
resize(data.length/2);
}
return res;
}
public E removeFirst() { //在头部删除
return remove(0);
}
public E removeLast() { //删除尾部元素
return remove(size-1);
}
//O(n)
@Override
public void removeElement(E e) { //删除元素
int index=find(e);//O(n)
if(index!=-1){
remove(index);//O(n)
}
}
private void resize(int newLen) { //扩容/缩容
E[] newData=(E[]) new Object[newLen];
for(int i=0;i<Math.min(data.length,newData.length);i++){
newData[i]=data[i];
}
data=newData;
}
public int getSize() { //获取有效长度
return this.size;
}
public boolean isEmpty() { //判断是否为空
return this.size==0;
}
//O(1)
public E get(int index) { //获取元素
if(index<0||index>=data.length){
throw new IllegalArgumentException("角标不存在!");
}
return data[index];
}
public E getFirst() { //获取头元素
return get(0);
}
public E getLast(){ //获取尾元素
return get(size-1);
}
public void set(int index, E e) { //改元素
if(index<0||index>=size){
throw new IllegalArgumentException("角标不存在!");
}
data[index]=e;
}
public int find(E e) { //寻找某元素
for(int i=0;i<size;i++){
if(data[i]==e){
return i;
}
}
return -1;
}
public boolean contains(E e) { //是否包含某元素
return find(e)!=-1;
}
public int getCapacity(){ //获取数组总长度
return data.length;
}
public void clear() { //清空数组
this.data=(E[]) new Object[DEFAULT_CAPACITY];
this.size=0;
}
public void swap(int i,int j){ //将两位置元素交换
if(i<0||i>=size||j<0||j>=size){
throw new IllegalArgumentException("角标非法!");
}
E temp=data[i];
data[i]=data[j];
data[j]=temp;
}
@Override
public String toString() { //重写toString方法
StringBuilder sb=new StringBuilder();
if(isEmpty()){
sb.append(String.format("ArrayList:[] %d/%d \n", size,data.length));
}else{
sb.append("ArrayList:[");
for(int i=0;i<size;i++){
if(i==size-1){
sb.append(data[i]+"]");
}else{
sb.append(data[i]+",");
}
}
sb.append(String.format(" %d/%d \n", size,data.length));
}
return sb.toString();
}
}
二,链表列表
使用链表实现列表。

-
增加元素
在头部增加,尾部增加,中间增加。
-
删除元素
在头部删除,尾部删除,中间删除。
-
获取有效长度
获取链表的有效长度。
-
判断列表是否为空
获取链表的有效长度是否为0。
-
获取末位置元素
尾指针所指的元素。
-
改变某位置的元素
根据链表的下标改变某下标的元素。
-
寻找元素
循环遍历链表判断元素是否相等。返回其下标。
-
列表是否包含某元素
和寻找元素一样,循环遍历l链表判断元素是否相等。
-
获取容积
获取链表的有效长度=总长度。
-
清除列表
-链表的有效长度size是标记链表某位置是否存在元素。
-直接将size置0。 -
重写toString方法
重新拼接字符串。打印输出。
代码:
package p02.动态链表;
import p01.动态数组.List;
public class LinkedList<E> implements List<E>{
private Node head; //头指针
private Node rear; //尾指针
private int size; //元素个数
public LinkedList(){
head=new Node(); //创建虚拟头结点
rear=head;
size=0;
}
private class Node{
E data;
Node next;
public Node(){
this(null,null);
}
public Node(E data){
this(data,null);
}
public Node(E data,Node next){
this.data=data;
this.next=next;
}
}
@Override
public int getSize() { //获取有效长度
return size;
}
@Override
public boolean isEmpty() { //是否为空
return size==0;
}
@Override
public void add(int index, E e) { //增加元素
if(index<0||index>size){
throw new IllegalArgumentException("角标非法!");
}
Node n=new Node(e);//封装节点
if(index==0){ //头插
n.next=head.next;
head.next=n;
if(isEmpty()){//第一次添加元素 要更新尾指针
rear=n;
}
}else if(index==size){ //尾插
n.next=rear.next;
rear.next=n;
rear=n;
}else{ //其余地方插
Node p=head;
for(int i=0;i<index;i++){
p=p.next;
}
n.next=p.next;
p.next=n;
}
size++;
}
@Override
public void addFirst(E e) { //头插
add(0,e);
}
@Override
public void addLast(E e) { //尾插
add(size,e);
}
@Override
public E get(int index) { //获取元素
if(index<0||index>=size){
throw new IllegalArgumentException("角标非法!");
}
if(index==0){ //表头
return head.next.data;
}else if(index==size-1){ //表尾
return rear.data;
}else{ //其余
Node p=head;
for(int i=0;i<=index;i++){
p=p.next;
}
return p.data;
}
}
@Override
public E getFirst() { //头部
return get(0);
}
@Override
public E getLast() { //尾部
return get(size-1);
}
@Override
public E remove(int index) { //删除元素
if(index<0||index>=size){
throw new IllegalArgumentException("角标非法!");
}
E res=null;
if(index==0){ //删头
Node n=head.next;
res=n.data;
head.next=n.next;
n=null;
if(size==1){ //删除最后一个元素,要更新尾指针
rear=head;
}
}else if(index==size-1){ //删尾
res=rear.data;
Node p=head;
while(p.next!=rear){
p=p.next;
}
p.next=rear.next;
rear=p;
}else{ //删其余
Node p=head;
for(int i=0;i<index;i++){
p=p.next;
}
Node n=p.next;
res=n.data;
p.next=n.next;
n=null;
}
size--;
return res;
}
@Override
public E removeFirst() { //删头
return remove(0);
}
@Override
public E removeLast() { //删尾
return remove(size-1);
}
@Override
public void set(int index, E e) { //改变元素
if(index<0||index>=size){
throw new IllegalArgumentException("角标非法");
}
Node p=head;
for(int i=0;i<=index;i++){
p=p.next;
}
p.data=e;
}
@Override
public boolean contains(E e) { //判断是否包含某元素
return find(e)!=-1;
}
@Override
public int find(E e) { //查找某元素
if(isEmpty()){
return -1;
}
int index=-1;
Node p=head;
while(p.next!=null){
index++;
p=p.next;
if(p.data.equals(e)){
return index;
}
}
return -1;
}
@Override
public void removeElement(E e) { //删除某元素
int index=find(e);
if(index!=-1){
remove(index);
}
}
@Override
public void clear() { //清除元素
head.next=null;
rear=head;
size=0;
}
@Override
public String toString() { //重写toString方法
StringBuilder sb=new StringBuilder();
if(isEmpty()){
return "[]";
}else{
sb.append("[");
Node p=head;
while(true){
p=p.next;
if(p==rear){
sb.append(p.data+"]");
break;
}else{
sb.append(p.data+",");
}
}
}
return sb.toString();
}
}
本文详细介绍了数据结构中的列表,包括顺序列表和链表列表两种实现方式。内容涵盖列表的基本操作,如增加、删除元素,判断空列表,获取有效长度及末尾元素,改变特定位置元素,查找元素,以及扩容、缩容策略。同时,提供了相关代码实现。
4万+

被折叠的 条评论
为什么被折叠?



